尝试这段代码。为什么getValueB()返回1而不是2?毕竟,递增两次被调用两次。
public class ReturningFromFinally { public static int getValueA() // This returns 2 as expected { try { return 1; } finally { return 2; } } public static int getValueB() // I expect this to return 2, but it returns 1 { try { return increment(); } finally { increment(); } } static int counter = 0; static int increment() { counter ++; return counter; } public static void main(String[] args) { System.out.println(getValueA()); // prints 2 as expected System.out.println(getValueB()); // why does it print 1? } }
毕竟,递增两次被调用两次。
是的,但是返回值是 在 第二次调用 之前 确定的。
返回的值由该 时间点在 return语句中的表达式求值确定,而不是“仅在执行离开方法之前”。
从JLS的14.17节开始:
一个带有Expression的return语句试图将控制权转移到包含它的方法的调用者;Expression的值成为方法调用的值。更准确地说, 执行这种return语句首先会评估Expression 。如果对表达式的求值由于某种原因而突然完成,则return语句由于该原因而突然完成。如果对表达式的求值正常完成,产生一个值V,则return语句突然完成,原因是返回值为V的返回值。
然后 根据JLS的14.20.2节,将执行转移到该finally块。但是,这不会重新评估return语句中的表达式。
finally
如果您的finally块是:
finally { return increment(); }
那么新的返回值将是该方法的最终结果(根据14.20.2节)-但您并未这样做。