java:尝试finally块执行
当存在return;
时,我对try-finally执行感到困惑return;
在try块中。 根据我的理解,finally块将始终执行,即在返回调用方法之前。 在考虑以下简单代码时:
public class TryCatchTest { public static void main(String[] args){ System.out.println(test()); } static int test(){ int x = 1; try{ return x; } finally{ x = x + 1; } } }
打印的结果实际为1.这是否表示finally块未执行? 任何人都可以帮助我吗?
从try
块返回时,返回值存储在该方法的堆栈帧中。 之后执行finally块。
更改finally块中的值不会更改堆栈上已有的值。 但是,如果再次从finally块返回,则将覆盖堆栈上的返回值,并返回新的x
。
如果在finally块中打印x
的值,您将知道它已执行,并且将打印x
的值。
static int test(){ int x = 1; try{ return x; } finally{ x = x + 1; System.out.println(x); // Prints new value of x } }
注意:如果返回引用值,则引用值将存储在堆栈中。 在这种情况下,您可以使用该引用更改object的值。
StringBuilder builder = new StringBuilder(""); try { builder.append("Rohit "); return builder; } finally { // Here you are changing the object pointed to by the reference builder.append("Jain"); // Return value will be `Rohit Jain` // However this will not nullify the return value. // The value returned will still be `Rohit Jain` builder = null; }
建议阅读:
- JVM规范 – 框架
执行finally块。 局部变量递增。 但是已经为返回值复制了该局部变量的值。
从Java语言规范, 14.17:返回语句 :
带有Expression的return语句尝试将控制权转移给包含它的方法的调用者; Expression的值成为方法调用的值。
…
前面的描述说“尝试转移控制”而不仅仅是“转移控制”,因为如果在try块或catch子句包含return语句的方法或构造函数中有任何try语句(§14.20),那么这些语句的任何finally子句在将控制权转移给方法或构造函数的调用者之前,try语句将按顺序执行,最内层到最外层。 突然完成finally子句可以破坏由return语句启动的控制转移
在退出尝试之前,您将返回x。 我会这样做:
public class TryCatchTest { public static void main(String[] args) { System.out.println(test()); } static int test() { int x = 1; try { do something with x. } finally { do something that will happen even in case of error; x = x + 1; return x; } } }