龙空技术网

java里的for循环

挨踢发满满 273

前言:

现在朋友们对“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循环