这里有四个问题,分别输出的结果是什么? 对于大多数人来说,前三个问题的输出都不成问题。关键在于最后一个问题,很多人可能没见过。 相信大家都知道,第一类问题的输出都是11,结果相同。因此很好理解。第二类问题也很好理解,输出的结果是10,11. 这里给大家解释一下,在运算中: 也就是说: 可能有的人在回答这个问题时,就会不小心掉坑里哦。我猜一下,有的人会说答案是11,11. 其实细心的人就会发现,第三类问题的答案和第二类的没区别,答案依旧是10,11. 我们来分析一下,为什么结果还是一样的呢。我们知道,i++与++i的区别就是一个先引用后增加,一个先增加后引用。如果你理解了这句话,这第三类问题就不攻自破了。他其实就是第二类问题的变形。 只不过不同的是,它把自身作为值的传递和存储对象了。会给我们造成一种错觉。 下面我从java字节码的角度带大家分析一下这个问题:(此处涉及jvm的知识,希望大家集中注意力) 首先,我将这个程序预编译成class类: 其实从这里,我们就可以看出一些头绪。 想要自己动手尝试的小伙伴,记得先将程序编译一下,快捷键是ctrl+shift+F9。然后再打开如下如所示位置即可查看被编译的class文件. 因此这里我就不用往下分析了。 想必很多小伙伴都不明白这一题输出的答案为什么是22,为什么不是21?心里肯定在想出题还能这样出! 答案马上揭晓。 首先,我们需要了解一个知识点。大家都听说过java程序要想运行起来,必须得在特定的java环境中。那么,这个环境中就由一个叫JVM的虚拟机来进行java程序的一切操作和管理。 在jvm中,虚拟机栈会对方法中的变量和操作进行处理。在虚拟机栈中,有一个局部变量表和操作数栈,他们两个相互配合,完成一个方法的变量赋值,四则运算! 说到这里,估计有的人已经有点懵了。那我就先上结果把! 结论:在进行表达式运算时,都是自右向左依次压入栈中 也就是下图的class文件所表示的这样! 其实这里的分析只是取巧,真正的分析因该是对他的字节码进行分析。 先附上它的字节码: 上面就是此程序的字节码文件! 为了便于大家理解,我在这里引用尚硅谷的宋红康老师的一张图大致表示一下:(此处的图并不匹配本程序,只是让大家看一下结构) 先解释一下马上要用到的几个操作: 下面我们要看得是问题四得那一部分指令: 下面是大致执行过程: 由于操作得指令比较多,所以博主偷了个懒,把有些指令合并成一张图表示了。希望大家见谅! 以上就是从字节码文件解释为啥输出结果是22,而不是21了。 表达式运算,先从右开始。因此从右自左入栈!i++ :先引用后增加 希望看到此篇博文的小伙伴,如果发现有什么不对的地方,欢迎在下方留言指正!博主一定虚心接受并改正!大家一起共同进步。如果对你有所帮助,可以给博主一个赞👍。
i++与++i的区别
在说i++与++i的区别之前,我们不妨来看一下下面这几行代码:
/** * 程序员面试过程中,常见的 i++ 与 ++i 的区别,这里需要从java的字节码文件进行分析 */ public void add(){ //第一类问题 int i1 = 10; i1++; System.out.println(i1); int i2 = 10; ++i2; System.out.println(i2); //第二类问题 int i3 = 10; int i4 = i3++; System.out.println(i4); int i5 = 10; int i6 = ++i5; System.out.println(i6); //第三类问题 int i7 = 10; i7 = i7++; System.out.println(i7); int i8 = 10; i8 = ++i8; System.out.println(i8); //第四类问题:重点,易错 int i9 = 10; int i10 = i9++ + ++i9; System.out.println(i10); }
第一,二类问题分析
i++ :先引用后增加
++i :先增加后引用
即
i++ :先在i所在的表达式中使用i的当前值,后让i加1
++i :让i先加1,然后在i所在的表达式中使用i的新值
在 int i4 = i3++;这个表达式中,先执行 i4 = i3,把i3的值赋给i4,之后i3才会进行+1操作。
在 int i6 = ++i5;这个表达式中,先执行 i3+1操作,之后在进行把i3的值赋给i4的操作。第三类问题分析
下面就是生成的class文件,此处被idea反编译回来了! public void add() { int i1 = 10; int i1 = i1 + 1; System.out.println(i1); int i2 = 10; int i2 = i2 + 1; System.out.println(i2); int i3 = 10; int var12 = i3 + 1; System.out.println(i3); int i5 = 10; int i5 = i5 + 1; System.out.println(i5); int i7 = 10; int var14 = i7 + 1; System.out.println(i7); int i8 = 10; int i8 = i8 + 1; System.out.println(i8); int i9 = 10; int i9 = i9 + 1; ++i9; int i10 = i9 + i9; System.out.println(i10); }
大家注意看这里:
此处就已经证实我之前说的,由于i++会先传值,在自增。所以i7会被先传值,而+1的值会被赋给一个新的临时变量存储起来。
而++i则会先自增,再传值,所以编译成class文件后,先自+1,后重新赋值回i8.
从而得到10,11这两个结果!
第四类问题(重难点)
因此,此处的 int i10 = i9++ + ++i9; 相当于先进行 ++i9,在进行 i10 = i9++的操作。
所以,此处的表达式就相当于i9 = i9 + 1; i10 = i9+i9; i9 = i9 + 1;
0 bipush 10 2 istore_0 3 iinc 0 by 1 6 getstatic #3 <java/lang/System.out> 9 iload_0 10 invokevirtual #4 <java/io/PrintStream.println> 13 bipush 10 15 istore_1 16 iinc 1 by 1 19 getstatic #3 <java/lang/System.out> 22 iload_1 23 invokevirtual #4 <java/io/PrintStream.println> 26 bipush 10 28 istore_2 29 iload_2 30 iinc 2 by 1 33 istore_3 34 getstatic #3 <java/lang/System.out> 37 iload_3 38 invokevirtual #4 <java/io/PrintStream.println> 41 bipush 10 43 istore 4 45 iinc 4 by 1 48 iload 4 50 istore 5 52 getstatic #3 <java/lang/System.out> 55 iload 5 57 invokevirtual #4 <java/io/PrintStream.println> 60 bipush 10 62 istore 6 64 iload 6 66 iinc 6 by 1 69 istore 6 71 getstatic #3 <java/lang/System.out> 74 iload 6 76 invokevirtual #4 <java/io/PrintStream.println> 79 bipush 10 81 istore 7 83 iinc 7 by 1 86 iload 7 88 istore 7 90 getstatic #3 <java/lang/System.out> 93 iload 7 95 invokevirtual #4 <java/io/PrintStream.println> 98 bipush 10 100 istore 8 102 iload 8 104 iinc 8 by 1 107 iinc 8 by 1 110 iload 8 112 iadd 113 istore 9 115 getstatic #3 <java/lang/System.out> 118 iload 9 120 invokevirtual #4 <java/io/PrintStream.println> 123 return
98 bipush 10 100 istore 8 102 iload 8 104 iinc 8 by 1 107 iinc 8 by 1 110 iload 8 112 iadd 113 istore 9 115 getstatic #3 <java/lang/System.out> 118 iload 9 120 invokevirtual #4 <java/io/PrintStream.println>
如果对字节码不理解的,建议就记住一个结论:
++i :先增加后引用。博主后记:
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算