谁能给我我解释一下这段程序的结果为什么是:2.而不是:3

时间:2020-12-12 10:02:08
class Test{
public int aaa(){
int x=1;

try{
return ++x;
}catch(Exception e){

}finally{
++x;
}
//System.out.println("atguigu");
return x;
}

public static void main(String[] args) {
Test t= new Test();
int y=t.aaa();
System.out.println(y);
}
}

24 个解决方案

#1


这涉及到finally{}语句块中操作与try{}语句块中的return的执行顺序,这段代码先执行了return ++i;  返回了2之后再执行finally{}语句块

#2


额…答得不太好……建议你找本书看看

#3


答案就在这篇博客中: 解析Java finally

#4


当程序执行到try语句块时,发现里面的第一条语句时return语句,就会去执行finally语句,++x之后等于2,然后不会再去执行try语句块,方法直接返回值2,所以不是3.

#5


综合一下:执行t.aaa()是,函数执行return ++x; 就将值返回给y(==2),由于x是局部变量,最后执行finally的++x也不会影响y的值;如果x是全局变量的话,y的值还是2,但此时x 的值变成3(与y无关),故关键代码还是return ++x 造成的

#6


5楼解释的挺好,顶一个。

#7


5楼解释的挺好,顶一个。
x实际上是3,只是在它是2的时候执行了return,所以y=2

#8


学到了,谢谢提出 谁能给我我解释一下这段程序的结果为什么是:2.而不是:3

#9


因为try的时候已经return了,只能执行一个return 所以就只返回2 咯~

#10


程序执行try块中return之前(包括return语句中的表达式运算)代码;再执行finally块,最后执行try中return;

在try中 已经执行了return 只是等待finally中的代码执行 然后完成try中的代码 也就完成了return 所以结果为2

#11


楼主问 了个好问题啊。
居然楼主问了为什么是2不是3,那么可以肯定,楼主已经知道了finally语句会执行的。楼主的疑问主要是居然执行了finally,那么应该会返回3才对啊。那问什么会是2呢?其实这里涉及到jvm的细节~~

看到很多人都赞成5楼的说法,我唯有怒站出来回答下,以免大家都抱着一个错误的说法。

先给一个最有说服力的答案:根据 java官方教程的jvm规范里的一段话就可以知道为什么了:
引用
If the try clause executes a return, the compiled code does the following:

1.Saves the return value (if any) in a local variable.

2.Executes a jsr to the code for the finally clause.

3.Upon return from the finally clause, returns the value saved in the local variable.


要翻译?:
如果try语句里有return,那么代码的行为如下:
1.如果有返回值,就把返回值保存到 局部变量中
2.执行jsr指令跳到finally语句里执行
3.执行完finally语句后,返回之前保存在局部变量表里的值

根据上面的说明就可以轻易地解释为什么是2了。
当执行到return ++x;时,jvm在执行完++x后会在局部变量表里另外分配一个空间来保存当前x的值。
注意,现在还没把值返回给y,而是继续执行finally语句里的语句。等执行完后再把之前保存的值(是2不是x)返回给y。
所以就有了y是2不是3的情况。

其实这里还有一点要注意的是,如果你在finally里也用了return语句,比如return +xx。那么y会是3。因为规范规定了,当try和finally里都有return时,会忽略try的return,而使用finally的return。

#12


11楼模范回答

#13


11楼说的好 谁能给我我解释一下这段程序的结果为什么是:2.而不是:3

#14


友情回复~~
如果还想要更详细的教程,请看我 针对这个问题专门写的一篇博客
如果还不懂就用板子拍死我把~~~ 不过请记住今天是愚人节~~

#15


到第一个return时候整个函数都结束了,后面的return就没有执行了,结果当然是2

例如break终止循环的一样,return相当于函数的结束符,后面的内容就不会执行了

#16


把x换成引用类型的属性,例如++a.x,最后的返回值a.x的值就是3了

#17


我想问的问题是。。为啥去掉catch。第二个return就报错了呢

#18


因为finally遇到return的时候 会先执行finally,,,,后执行return,,,,,,
但是你的finally里面已经return过了,,所以try里面的return就不会执行了

#19


,,, - - 看走眼了,,,

#20


引用 5 楼 wzgl708937822 的回复:
综合一下:执行t.aaa()是,函数执行return ++x; 就将值返回给y(==2),由于x是局部变量,最后执行finally的++x也不会影响y的值;如果x是全局变量的话,y的值还是2,但此时x 的值变成3(与y无关),故关键代码还是return ++x 造成的

建议,回去多看看基本知识再来解答。谢谢。

#21


引用 11 楼 ZJL_foxfire 的回复:
楼主问 了个好问题啊。
居然楼主问了为什么是2不是3,那么可以肯定,楼主已经知道了finally语句会执行的。楼主的疑问主要是居然执行了finally,那么应该会返回3才对啊。那问什么会是2呢?其实这里涉及到jvm的细节~~

看到很多人都赞成5楼的说法,我唯有怒站出来回答下,以免大家都抱着一个错误的说法。

先给一个最有说服力的答案:根据 java官方教程的jvm规范里的一段话就可以知道为什么了:
引用
If the try clause executes a return, the compiled code does the following:

1.Saves the return value (if any) in a local variable.

2.Executes a jsr to the code for the finally clause.

3.Upon return from the finally clause, returns the value saved in the local variable.


要翻译?:
如果try语句里有return,那么代码的行为如下:
1.如果有返回值,就把返回值保存到 局部变量中
2.执行jsr指令跳到finally语句里执行
3.执行完finally语句后,返回之前保存在局部变量表里的值

根据上面的说明就可以轻易地解释为什么是2了。
当执行到return ++x;时,jvm在执行完++x后会在局部变量表里另外分配一个空间来保存当前x的值。
注意,现在还没把值返回给y,而是继续执行finally语句里的语句。等执行完后再把之前保存的值(是2不是x)返回给y。
所以就有了y是2不是3的情况。

其实这里还有一点要注意的是,如果你在finally里也用了return语句,比如return +xx。那么y会是3。因为规范规定了,当try和finally里都有return时,会忽略try的return,而使用finally的return。


解释的一般,因为最后你举例的时候,例子举得不错,但是你给的结果是错的。所以证明了:1你真的是疏忽了。2之前你给的答案也是临时抱佛脚,理解的也是一半一半。

#22


11楼强,赞一个

#23


楼上说的都很对我就不强调了

#24


该回复于2015-04-08 15:06:39被管理员删除

#1


这涉及到finally{}语句块中操作与try{}语句块中的return的执行顺序,这段代码先执行了return ++i;  返回了2之后再执行finally{}语句块

#2


额…答得不太好……建议你找本书看看

#3


答案就在这篇博客中: 解析Java finally

#4


当程序执行到try语句块时,发现里面的第一条语句时return语句,就会去执行finally语句,++x之后等于2,然后不会再去执行try语句块,方法直接返回值2,所以不是3.

#5


综合一下:执行t.aaa()是,函数执行return ++x; 就将值返回给y(==2),由于x是局部变量,最后执行finally的++x也不会影响y的值;如果x是全局变量的话,y的值还是2,但此时x 的值变成3(与y无关),故关键代码还是return ++x 造成的

#6


5楼解释的挺好,顶一个。

#7


5楼解释的挺好,顶一个。
x实际上是3,只是在它是2的时候执行了return,所以y=2

#8


学到了,谢谢提出 谁能给我我解释一下这段程序的结果为什么是:2.而不是:3

#9


因为try的时候已经return了,只能执行一个return 所以就只返回2 咯~

#10


程序执行try块中return之前(包括return语句中的表达式运算)代码;再执行finally块,最后执行try中return;

在try中 已经执行了return 只是等待finally中的代码执行 然后完成try中的代码 也就完成了return 所以结果为2

#11


楼主问 了个好问题啊。
居然楼主问了为什么是2不是3,那么可以肯定,楼主已经知道了finally语句会执行的。楼主的疑问主要是居然执行了finally,那么应该会返回3才对啊。那问什么会是2呢?其实这里涉及到jvm的细节~~

看到很多人都赞成5楼的说法,我唯有怒站出来回答下,以免大家都抱着一个错误的说法。

先给一个最有说服力的答案:根据 java官方教程的jvm规范里的一段话就可以知道为什么了:
引用
If the try clause executes a return, the compiled code does the following:

1.Saves the return value (if any) in a local variable.

2.Executes a jsr to the code for the finally clause.

3.Upon return from the finally clause, returns the value saved in the local variable.


要翻译?:
如果try语句里有return,那么代码的行为如下:
1.如果有返回值,就把返回值保存到 局部变量中
2.执行jsr指令跳到finally语句里执行
3.执行完finally语句后,返回之前保存在局部变量表里的值

根据上面的说明就可以轻易地解释为什么是2了。
当执行到return ++x;时,jvm在执行完++x后会在局部变量表里另外分配一个空间来保存当前x的值。
注意,现在还没把值返回给y,而是继续执行finally语句里的语句。等执行完后再把之前保存的值(是2不是x)返回给y。
所以就有了y是2不是3的情况。

其实这里还有一点要注意的是,如果你在finally里也用了return语句,比如return +xx。那么y会是3。因为规范规定了,当try和finally里都有return时,会忽略try的return,而使用finally的return。

#12


11楼模范回答

#13


11楼说的好 谁能给我我解释一下这段程序的结果为什么是:2.而不是:3

#14


友情回复~~
如果还想要更详细的教程,请看我 针对这个问题专门写的一篇博客
如果还不懂就用板子拍死我把~~~ 不过请记住今天是愚人节~~

#15


到第一个return时候整个函数都结束了,后面的return就没有执行了,结果当然是2

例如break终止循环的一样,return相当于函数的结束符,后面的内容就不会执行了

#16


把x换成引用类型的属性,例如++a.x,最后的返回值a.x的值就是3了

#17


我想问的问题是。。为啥去掉catch。第二个return就报错了呢

#18


因为finally遇到return的时候 会先执行finally,,,,后执行return,,,,,,
但是你的finally里面已经return过了,,所以try里面的return就不会执行了

#19


,,, - - 看走眼了,,,

#20


引用 5 楼 wzgl708937822 的回复:
综合一下:执行t.aaa()是,函数执行return ++x; 就将值返回给y(==2),由于x是局部变量,最后执行finally的++x也不会影响y的值;如果x是全局变量的话,y的值还是2,但此时x 的值变成3(与y无关),故关键代码还是return ++x 造成的

建议,回去多看看基本知识再来解答。谢谢。

#21


引用 11 楼 ZJL_foxfire 的回复:
楼主问 了个好问题啊。
居然楼主问了为什么是2不是3,那么可以肯定,楼主已经知道了finally语句会执行的。楼主的疑问主要是居然执行了finally,那么应该会返回3才对啊。那问什么会是2呢?其实这里涉及到jvm的细节~~

看到很多人都赞成5楼的说法,我唯有怒站出来回答下,以免大家都抱着一个错误的说法。

先给一个最有说服力的答案:根据 java官方教程的jvm规范里的一段话就可以知道为什么了:
引用
If the try clause executes a return, the compiled code does the following:

1.Saves the return value (if any) in a local variable.

2.Executes a jsr to the code for the finally clause.

3.Upon return from the finally clause, returns the value saved in the local variable.


要翻译?:
如果try语句里有return,那么代码的行为如下:
1.如果有返回值,就把返回值保存到 局部变量中
2.执行jsr指令跳到finally语句里执行
3.执行完finally语句后,返回之前保存在局部变量表里的值

根据上面的说明就可以轻易地解释为什么是2了。
当执行到return ++x;时,jvm在执行完++x后会在局部变量表里另外分配一个空间来保存当前x的值。
注意,现在还没把值返回给y,而是继续执行finally语句里的语句。等执行完后再把之前保存的值(是2不是x)返回给y。
所以就有了y是2不是3的情况。

其实这里还有一点要注意的是,如果你在finally里也用了return语句,比如return +xx。那么y会是3。因为规范规定了,当try和finally里都有return时,会忽略try的return,而使用finally的return。


解释的一般,因为最后你举例的时候,例子举得不错,但是你给的结果是错的。所以证明了:1你真的是疏忽了。2之前你给的答案也是临时抱佛脚,理解的也是一半一半。

#22


11楼强,赞一个

#23


楼上说的都很对我就不强调了

#24


该回复于2015-04-08 15:06:39被管理员删除