详解java面试题中的i++和++i
代码如下所示:
publicclassTestPlusPlus{ publicstaticvoidmain(String[]args){ intk=addAfterReturn(10); System.out.println(k);//输出10 intk1=addbeforeReturn(10); System.out.println(k1);//输出11 } publicstaticintaddbeforeReturn(inti){ return++i; } publicstaticintaddAfterReturn(inti){ returni++; } }
我们从字节码层面来看,
addAfterReturn的字节码如下:
0:iload_0 1:iinc0,1 4:ireturn
很简单,iload_0表示将局部变量表中索引为0的元素的值放到栈顶。所以讲传入的i的值放入到栈顶,其次iinc0,1表示将局部变量表中
索引为0的元素进行加1,最后是ireturn将栈顶的int值放入到调用者栈桢的栈中。(这里的栈都是操作数栈)
因此其实iinc0,1并没有实际影响到返回的值,所以返回依旧是10.
同理addBeforeReturn字节码如下:
0:iinc0,1 3:iload_0 4:ireturn
这里就留给大家自己分析,其实很明显可以看出,这里是先进行递增然后才入栈了。所以返回的值其实是递增了。
现在让我们来做一道我自己改过的面试题。
publicclassTestPlusPlus2{ static{ x=5; inty=10; } staticintx,y; publicstaticvoidmain(Stringargs[]){ x--; myMethod(); System.out.println(x+y+++x); } publicstaticvoidmyMethod(){ y=x+++++x; } }
知道答案了吗?运行一下,正确答案是23.
如果你真正理解了上面的,这道题也很简单,首先是在执行main之前,知道x,y的值,这里有点牵扯到类加载机制,类加载的准备阶段会为static变量赋值为该类型的零值。int的话就对应0喽,在类的初始化阶段,根据代码顺序收集类中的静态块和静态变量赋值行为进行生成方法。因此该测验中,x=5,y=0;
继续分析,在执行myMethod之前执行了x--',所以x=4,y=0,myMethod中y=x+++++x;
x++在执行后面的加操作之前是不会加1的,就跟returni++在return之后才会进行i++,(这里的return你可以理解为上面的iload入栈操作,而不是iretrun这条指令),所以第一个加数为4,但是这里需要注意的是在执行++x之前,递增已经对实际的x生效了,即x已经为5了,所以第二个加数为++i为6,从而y=10.
随后就很简单了x+y+++x为6+10+7为23。幸运的是如果你能看懂字节码,你可以翻译该代码的字节码,用字节码来验算,也可以发现这样的结果。
再来看一道例子,是群里大佬提供的。我觉得也很针对基础。
publicstaticintplus(inti){ try{ ++i; System.out.println("try"); returni++; }finally{ System.out.println("finally"); i++; //returni; } } publicstaticvoidmain(String[]args){ System.out.println(Test1.plus(5)); }
你能想到最后输出的是多少吗?如果去掉注释呢,这也就是为什么finally块里不要return的原因。因为无论对错,可能永远都返回某个值。
总结
以上所述是小编给大家介绍的详解java面试题中的i++和++i,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!