在java中,规定先执行finally中的代码,再return。但是看过这么一段代码,如下
public class Bruce
{
static int deal(int a)
{
try{
a++;
return a;
}
finally
{
a++;
}
}
public static void main(String[] args)
{
System.out.println("The result is "+deal(5));
}
}
得到结果为:The result is 6
我认为当执行到return a;时,程序将变量a保护起来,再执行finally中代码,最后return a的值
不知道各位怎样认为?
30 个解决方案
#1
java中没这规定吧,只是说finally中的代码最后是必须执行的
#2
应该是这样,把那个函数改成如下:
static int deal(int a)
{
try{
a++;
return a;
}
finally
{
a++;
System.out.print("finally");
}
}
结果:
finally6
可以看出finally
中的代码在return前执行.
static int deal(int a)
{
try{
a++;
return a;
}
finally
{
a++;
System.out.print("finally");
}
}
结果:
finally6
可以看出finally
中的代码在return前执行.
#3
我覺得不是這樣啊
try裏面的return已經返回值了,因此雖然finally里的語句執行到了,卻不能對return有影響,所以得到的結果是6
樓主的説法我贊成
try裏面的return已經返回值了,因此雖然finally里的語句執行到了,卻不能對return有影響,所以得到的結果是6
樓主的説法我贊成
#4
楼主的意思是,为什么在finally里面自增的a不能返回?而返回的是自增前的a
#5
你可以再看看这个,返回都是in finally
public class Bruce {
static T deal(T t) {
try {
t.s = "in try";
return t;
} finally {
t.s = "in finally";
System.out.println(t);
}
}
public static void main(String[] args) {
T t = new T();
System.out.println(deal(t));
}
}
class T {
String s;
public String toString() {
return s;
}
}
public class Bruce {
static T deal(T t) {
try {
t.s = "in try";
return t;
} finally {
t.s = "in finally";
System.out.println(t);
}
}
public static void main(String[] args) {
T t = new T();
System.out.println(deal(t));
}
}
class T {
String s;
public String toString() {
return s;
}
}
#6
我感觉是return a和finally里面的a其实已经不是同一个a了,原因是a不是类,不是引用,不知道理解对不对
#7
结果是这样的:
当程序运行到return时,jvm把返回值保存在一个临时的对象中去了。并不是说程序在此时退出。相反程序需要执行finally中的语句。不管是什么情况,只要有finally语句,程序最后都要执行。
当程序运行到return时,jvm把返回值保存在一个临时的对象中去了。并不是说程序在此时退出。相反程序需要执行finally中的语句。不管是什么情况,只要有finally语句,程序最后都要执行。
#8
public class Bruce extends java.lang.Object {
public Bruce();
static int deal(int);
public static void main(java.lang.String[]);
}
Method Bruce()
0 aload_0
1 invokespecial #1 <Method java.lang.Object()>
4 return
Method int deal(int)
0 iinc 0 1
3 iload_0
4 istore_1
5 jsr 16
8 iload_1
9 ireturn
10 astore_2
11 jsr 16
14 aload_2
15 athrow
16 astore_3
17 iinc 0 1
20 ret 3
Exception table:
from to target type
0 8 10 any
10 14 10 any
Method void main(java.lang.String[])
0 getstatic #2 <Field java.io.PrintStream out>
3 new #3 <Class java.lang.StringBuffer>
6 dup
7 invokespecial #4 <Method java.lang.StringBuffer()>
10 ldc #5 <String "The result is ">
12 invokevirtual #6 <Method java.lang.StringBuffer append(java.lang.String)>
15 iconst_5
16 invokestatic #7 <Method int deal(int)>
19 invokevirtual #8 <Method java.lang.StringBuffer append(int)>
22 invokevirtual #9 <Method java.lang.String toString()>
25 invokevirtual #10 <Method void println(java.lang.String)>
28 return
public Bruce();
static int deal(int);
public static void main(java.lang.String[]);
}
Method Bruce()
0 aload_0
1 invokespecial #1 <Method java.lang.Object()>
4 return
Method int deal(int)
0 iinc 0 1
3 iload_0
4 istore_1
5 jsr 16
8 iload_1
9 ireturn
10 astore_2
11 jsr 16
14 aload_2
15 athrow
16 astore_3
17 iinc 0 1
20 ret 3
Exception table:
from to target type
0 8 10 any
10 14 10 any
Method void main(java.lang.String[])
0 getstatic #2 <Field java.io.PrintStream out>
3 new #3 <Class java.lang.StringBuffer>
6 dup
7 invokespecial #4 <Method java.lang.StringBuffer()>
10 ldc #5 <String "The result is ">
12 invokevirtual #6 <Method java.lang.StringBuffer append(java.lang.String)>
15 iconst_5
16 invokestatic #7 <Method int deal(int)>
19 invokevirtual #8 <Method java.lang.StringBuffer append(int)>
22 invokevirtual #9 <Method java.lang.String toString()>
25 invokevirtual #10 <Method void println(java.lang.String)>
28 return
#9
把static 去掉
#10
kypfos(人群中我找不到你)的解释是正解
当执行到return时,会把当前的a(a=6)值压栈,再去执行finally代码段把处理后的a值(a=7)压到另一地方,返回的时候,JVM取的是第一次压栈的值a=6
当执行到return时,会把当前的a(a=6)值压栈,再去执行finally代码段把处理后的a值(a=7)压到另一地方,返回的时候,JVM取的是第一次压栈的值a=6
#11
用javap -c Bruce就可以看到java指令代码
#12
return a;前有store动作,转去执行finally;
执行完finally再load a值返回。
执行完finally再load a值返回。
#13
kypfos(人群中我找不到你)能解釋一下關鍵的語句嗎?
#14
希望kypfos(人群中我找不到你) 能把每个指令具体解释下
#15
这个问题以前没想过哈,只知道用着没有没错
#16
up
#17
mark
#18
关注中^
#19
我运行这条怎么 Could not found Bruce ?
要啥版本?
要啥版本?
#20
楼上的头晕了把? Bruce是类名.
你只需要javap -c classname 就行了 !
^_^
你只需要javap -c classname 就行了 !
^_^
#21
kypfos(人群中我找不到你) 麻烦可以解释下那些关键代码都是做什么用的吗???关注中.......
#22
深入java虚拟机里面好像有讲!
#23
应该可以这样理解了:
在return之前,finally里的语句都会执行.在finally之前回保存,基本类型保存的是值,而对象保存的是引用.在finally执行之后,会load保存的值返回.楼主的例子里是基本类型所以返回的值是6,而forair(forair) 的例子里保存的是T的引用,所以finally中改变了T中的值,当return的时候,返回的是T的引用,所以后来print的结果都是"in finally"
在return之前,finally里的语句都会执行.在finally之前回保存,基本类型保存的是值,而对象保存的是引用.在finally执行之后,会load保存的值返回.楼主的例子里是基本类型所以返回的值是6,而forair(forair) 的例子里保存的是T的引用,所以finally中改变了T中的值,当return的时候,返回的是T的引用,所以后来print的结果都是"in finally"
#24
哈哈,我很喜欢 kypfos 查看问题的方法,这样可能对深入理解一些概念性的问题大有帮助。
不过这里如果用一句简单的话来解释,可以是:
“在非void函数过程体中,可以有任意多个return语句,但只返回运行过程中的第一个返回参数。”
所以当运行到第一个return语句时,返回参数就已经被锁定了,不过深入查看指令代码确实让我们大家又理解了JAVA底层是如何实现的。^^
另:在void函数体中,运行时一旦遇到return;语句,则立刻离开函数体,但无论如何finally块中的语句将始终执行。
@.@||~
不过这里如果用一句简单的话来解释,可以是:
“在非void函数过程体中,可以有任意多个return语句,但只返回运行过程中的第一个返回参数。”
所以当运行到第一个return语句时,返回参数就已经被锁定了,不过深入查看指令代码确实让我们大家又理解了JAVA底层是如何实现的。^^
另:在void函数体中,运行时一旦遇到return;语句,则立刻离开函数体,但无论如何finally块中的语句将始终执行。
@.@||~
#25
up
#26
up
#27
其实finally中的a++被执行了,只所以你的到的结果是6是因为你在try中就返回了a,这样deal的所有环境被保存在了堆栈中,包括返回值。当执行完finally块后恢复堆栈中的deal环境变量,因此你的到的结果是6。如果改称下列形式就会返回7。
static int deal(int a)
{
try{
a++;
return a;
}
finally
{
a++;
System.out.print("finally");
return a; //加上此句
}
}
static int deal(int a)
{
try{
a++;
return a;
}
finally
{
a++;
System.out.print("finally");
return a; //加上此句
}
}
#28
up
#29
up
#30
我覺得返回結果和參數類型有關,因為在try中的return語句把要返回的值暫存到一個臨時對象中,而當函數中的參數為對象時,在finally中的語句如果執行了對該臨時對象的值的改變,則會引起最後結果 的改變!
不知道能否這樣理解!
請高人分析!up!@~~~~~~~~~~~~~~~
不知道能否這樣理解!
請高人分析!up!@~~~~~~~~~~~~~~~
#1
java中没这规定吧,只是说finally中的代码最后是必须执行的
#2
应该是这样,把那个函数改成如下:
static int deal(int a)
{
try{
a++;
return a;
}
finally
{
a++;
System.out.print("finally");
}
}
结果:
finally6
可以看出finally
中的代码在return前执行.
static int deal(int a)
{
try{
a++;
return a;
}
finally
{
a++;
System.out.print("finally");
}
}
结果:
finally6
可以看出finally
中的代码在return前执行.
#3
我覺得不是這樣啊
try裏面的return已經返回值了,因此雖然finally里的語句執行到了,卻不能對return有影響,所以得到的結果是6
樓主的説法我贊成
try裏面的return已經返回值了,因此雖然finally里的語句執行到了,卻不能對return有影響,所以得到的結果是6
樓主的説法我贊成
#4
楼主的意思是,为什么在finally里面自增的a不能返回?而返回的是自增前的a
#5
你可以再看看这个,返回都是in finally
public class Bruce {
static T deal(T t) {
try {
t.s = "in try";
return t;
} finally {
t.s = "in finally";
System.out.println(t);
}
}
public static void main(String[] args) {
T t = new T();
System.out.println(deal(t));
}
}
class T {
String s;
public String toString() {
return s;
}
}
public class Bruce {
static T deal(T t) {
try {
t.s = "in try";
return t;
} finally {
t.s = "in finally";
System.out.println(t);
}
}
public static void main(String[] args) {
T t = new T();
System.out.println(deal(t));
}
}
class T {
String s;
public String toString() {
return s;
}
}
#6
我感觉是return a和finally里面的a其实已经不是同一个a了,原因是a不是类,不是引用,不知道理解对不对
#7
结果是这样的:
当程序运行到return时,jvm把返回值保存在一个临时的对象中去了。并不是说程序在此时退出。相反程序需要执行finally中的语句。不管是什么情况,只要有finally语句,程序最后都要执行。
当程序运行到return时,jvm把返回值保存在一个临时的对象中去了。并不是说程序在此时退出。相反程序需要执行finally中的语句。不管是什么情况,只要有finally语句,程序最后都要执行。
#8
public class Bruce extends java.lang.Object {
public Bruce();
static int deal(int);
public static void main(java.lang.String[]);
}
Method Bruce()
0 aload_0
1 invokespecial #1 <Method java.lang.Object()>
4 return
Method int deal(int)
0 iinc 0 1
3 iload_0
4 istore_1
5 jsr 16
8 iload_1
9 ireturn
10 astore_2
11 jsr 16
14 aload_2
15 athrow
16 astore_3
17 iinc 0 1
20 ret 3
Exception table:
from to target type
0 8 10 any
10 14 10 any
Method void main(java.lang.String[])
0 getstatic #2 <Field java.io.PrintStream out>
3 new #3 <Class java.lang.StringBuffer>
6 dup
7 invokespecial #4 <Method java.lang.StringBuffer()>
10 ldc #5 <String "The result is ">
12 invokevirtual #6 <Method java.lang.StringBuffer append(java.lang.String)>
15 iconst_5
16 invokestatic #7 <Method int deal(int)>
19 invokevirtual #8 <Method java.lang.StringBuffer append(int)>
22 invokevirtual #9 <Method java.lang.String toString()>
25 invokevirtual #10 <Method void println(java.lang.String)>
28 return
public Bruce();
static int deal(int);
public static void main(java.lang.String[]);
}
Method Bruce()
0 aload_0
1 invokespecial #1 <Method java.lang.Object()>
4 return
Method int deal(int)
0 iinc 0 1
3 iload_0
4 istore_1
5 jsr 16
8 iload_1
9 ireturn
10 astore_2
11 jsr 16
14 aload_2
15 athrow
16 astore_3
17 iinc 0 1
20 ret 3
Exception table:
from to target type
0 8 10 any
10 14 10 any
Method void main(java.lang.String[])
0 getstatic #2 <Field java.io.PrintStream out>
3 new #3 <Class java.lang.StringBuffer>
6 dup
7 invokespecial #4 <Method java.lang.StringBuffer()>
10 ldc #5 <String "The result is ">
12 invokevirtual #6 <Method java.lang.StringBuffer append(java.lang.String)>
15 iconst_5
16 invokestatic #7 <Method int deal(int)>
19 invokevirtual #8 <Method java.lang.StringBuffer append(int)>
22 invokevirtual #9 <Method java.lang.String toString()>
25 invokevirtual #10 <Method void println(java.lang.String)>
28 return
#9
把static 去掉
#10
kypfos(人群中我找不到你)的解释是正解
当执行到return时,会把当前的a(a=6)值压栈,再去执行finally代码段把处理后的a值(a=7)压到另一地方,返回的时候,JVM取的是第一次压栈的值a=6
当执行到return时,会把当前的a(a=6)值压栈,再去执行finally代码段把处理后的a值(a=7)压到另一地方,返回的时候,JVM取的是第一次压栈的值a=6
#11
用javap -c Bruce就可以看到java指令代码
#12
return a;前有store动作,转去执行finally;
执行完finally再load a值返回。
执行完finally再load a值返回。
#13
kypfos(人群中我找不到你)能解釋一下關鍵的語句嗎?
#14
希望kypfos(人群中我找不到你) 能把每个指令具体解释下
#15
这个问题以前没想过哈,只知道用着没有没错
#16
up
#17
mark
#18
关注中^
#19
我运行这条怎么 Could not found Bruce ?
要啥版本?
要啥版本?
#20
楼上的头晕了把? Bruce是类名.
你只需要javap -c classname 就行了 !
^_^
你只需要javap -c classname 就行了 !
^_^
#21
kypfos(人群中我找不到你) 麻烦可以解释下那些关键代码都是做什么用的吗???关注中.......
#22
深入java虚拟机里面好像有讲!
#23
应该可以这样理解了:
在return之前,finally里的语句都会执行.在finally之前回保存,基本类型保存的是值,而对象保存的是引用.在finally执行之后,会load保存的值返回.楼主的例子里是基本类型所以返回的值是6,而forair(forair) 的例子里保存的是T的引用,所以finally中改变了T中的值,当return的时候,返回的是T的引用,所以后来print的结果都是"in finally"
在return之前,finally里的语句都会执行.在finally之前回保存,基本类型保存的是值,而对象保存的是引用.在finally执行之后,会load保存的值返回.楼主的例子里是基本类型所以返回的值是6,而forair(forair) 的例子里保存的是T的引用,所以finally中改变了T中的值,当return的时候,返回的是T的引用,所以后来print的结果都是"in finally"
#24
哈哈,我很喜欢 kypfos 查看问题的方法,这样可能对深入理解一些概念性的问题大有帮助。
不过这里如果用一句简单的话来解释,可以是:
“在非void函数过程体中,可以有任意多个return语句,但只返回运行过程中的第一个返回参数。”
所以当运行到第一个return语句时,返回参数就已经被锁定了,不过深入查看指令代码确实让我们大家又理解了JAVA底层是如何实现的。^^
另:在void函数体中,运行时一旦遇到return;语句,则立刻离开函数体,但无论如何finally块中的语句将始终执行。
@.@||~
不过这里如果用一句简单的话来解释,可以是:
“在非void函数过程体中,可以有任意多个return语句,但只返回运行过程中的第一个返回参数。”
所以当运行到第一个return语句时,返回参数就已经被锁定了,不过深入查看指令代码确实让我们大家又理解了JAVA底层是如何实现的。^^
另:在void函数体中,运行时一旦遇到return;语句,则立刻离开函数体,但无论如何finally块中的语句将始终执行。
@.@||~
#25
up
#26
up
#27
其实finally中的a++被执行了,只所以你的到的结果是6是因为你在try中就返回了a,这样deal的所有环境被保存在了堆栈中,包括返回值。当执行完finally块后恢复堆栈中的deal环境变量,因此你的到的结果是6。如果改称下列形式就会返回7。
static int deal(int a)
{
try{
a++;
return a;
}
finally
{
a++;
System.out.print("finally");
return a; //加上此句
}
}
static int deal(int a)
{
try{
a++;
return a;
}
finally
{
a++;
System.out.print("finally");
return a; //加上此句
}
}
#28
up
#29
up
#30
我覺得返回結果和參數類型有關,因為在try中的return語句把要返回的值暫存到一個臨時對象中,而當函數中的參數為對象時,在finally中的語句如果執行了對該臨時對象的值的改變,則會引起最後結果 的改變!
不知道能否這樣理解!
請高人分析!up!@~~~~~~~~~~~~~~~
不知道能否這樣理解!
請高人分析!up!@~~~~~~~~~~~~~~~