前言:
现在朋友们对“java增强的for循环”都比较关注,你们都想要了解一些“java增强的for循环”的相关知识。那么小编在网上汇集了一些关于“java增强的for循环””的相关内容,希望看官们能喜欢,各位老铁们一起来学习一下吧!从字节码角度再来分析一下,java里的for循环是怎么做到的。既然是字节码角度,那一定是在操作栈和局部变量表来实现的。先看一下源代码:
很简单的一个代码,循环10次,每次循环打印输出i。
我们再使用javap -v命令来解析class文件:
初始的时候,栈和局部变量表如下:
栈顶:空,局部变量表:[this, 空,...]
0: iconst_0:iconst表示直接加载int类型的常数,常数值为0,到栈顶,这个0其实就是for循环里i=0这一句。
栈顶:0,局部变量表:[this, 空,...]
1: istore_1:istore表示将栈顶弹出保存到局部变量表,_1表示保存到局部变量表槽位1的地方。
栈顶:空,局部变量表:[this, 0,...]
2: iload_1:iload表示从局部变量表加载到栈顶,_1表示槽位为1。
栈顶:0,局部变量表:[this, 0,...]
3: bipush 10:这里的bipush和iconst类似,也是加载常量的指令,jvm为了效率考虑,优化了常量加载的指令,所以这里的意思是加载10这个常量到栈顶,原来栈顶的0被下压。
栈顶:10,局部变量表:[this, 0,...]
0
5: if_icmpge 21:icmpge是一个比较int类型的指令,意思为弹出栈顶和次栈顶的值,并比较,ge:表示大于等于,整句话的意思为:次栈顶的元素>=栈顶元素时,程序跳到21行,21行也就是21: return返回。
栈顶:空,局部变量表:[this, 0,...]
8: getstatic #2:获取静态对象,这里也就是System.out对象。
11: iload_1:从局部变量表1槽位load值到栈顶。
栈顶:0,局部变量表:[this, 0,...]
12: invokevirtual #3:这里就是调用println方法,并把栈顶值弹出,作为参数打印。
栈顶:空,局部变量表:[this, 0,...]
15: iinc 1, 1:对局部变量表槽位1位置的值做+1。
栈顶:空,局部变量表:[this, 1,...]
18: goto 2:程序跳转到第二行继续执行,也就是2: iload_1
21: return:程序结束返回。
整个流程清晰明了,我们可以看到,for循环在字节码层面其实是一个比较指令if_icmpge+goto的流程控制,for关键字其实也只是一个java语法层面的语法糖。
标签: #java增强的for循环