3 回答
TA贡献1852条经验 获得超1个赞
该try
块在执行return
语句s
时完成,return
语句执行时的值是方法返回的值。该finally
子句稍后更改s
(在return
语句完成之后)的值不会(在该点)更改返回值。
请注意,上述内容涉及块中s
自身值的更改finally
,而不是s
引用的对象。如果s
是对可变对象的引用(String
不是)并且在块中更改了对象的内容finally
,那么将在返回的值中看到这些更改。
有关所有这些操作的详细规则可以在Java语言规范的第14.20.2节中找到。请注意,return
语句的执行计为try
块的突然终止(开始的部分“ 如果执行块因任何其他原因而突然完成R .... ”适用)。有关语句突然终止块的原因,请参见JLS的第14.17节return
。
通过进一步的细节:如果语句的try
块和finally
块都try-finally
因return
语句而突然终止,那么§14.20.2中的以下规则适用:
如果
try
由于任何其他原因R [除了抛出异常]而突然完成finally
块的执行,则执行该块,然后有一个选择:
如果
finally
块正常完成,则try
语句突然完成,原因是R.如果
finally
块因原因S而突然完成,则try
语句突然完成,原因为S(并且原因R被丢弃)。
结果是块中的return
语句finally
确定整个try-finally
语句的返回值,并且try
丢弃块中返回的值。try-catch-finally
如果try
块抛出异常,它会被catch
块捕获,并且catch
块和finally
块都有return
语句,那么在语句中会发生类似的事情。
TA贡献1828条经验 获得超3个赞
如果我们查看字节码内部,我们会注意到JDK已经进行了重大优化,而foo()方法看起来像:
String tmp = null;
try {
s = "dev"
tmp = s;
s = "override variable s";
return tmp;
} catch (RuntimeException e){
s = "override variable s";
throw e;
}
和字节码:
0: ldc #7; //loading String "dev"
2: putstatic #8; //storing it to a static variable
5: getstatic #8; //loading "dev" from a static variable
8: astore_0 //storing "dev" to a temp variable
9: ldc #9; //loading String "override variable s"
11: putstatic #8; //setting a static variable
14: aload_0 //loading a temp avariable
15: areturn //returning it
16: astore_1
17: ldc #9; //loading String "override variable s"
19: putstatic #8; //setting a static variable
22: aload_1
23: athrow
java保留“dev”字符串在返回之前被更改。事实上,这根本没有最终阻止。
添加回答
举报