考虑到这段代码,我可以吗? 绝对肯定 那个 finally
无论如何,块总是执行 something()
是什么?
try {
something();
return success;
}
catch (Exception e) {
return failure;
}
finally {
System.out.println("i don't know if this will get printed out.");
}
考虑到这段代码,我可以吗? 绝对肯定 那个 finally
无论如何,块总是执行 something()
是什么?
try {
something();
return success;
}
catch (Exception e) {
return failure;
}
finally {
System.out.println("i don't know if this will get printed out.");
}
是, finally
将在执行try或catch代码块后调用。
唯一的一次 finally
将不会被称为:
System.exit()
;try
要么 catch
块;示例代码:
public static void main(String[] args) {
System.out.println(Test.test());
}
public static int test() {
try {
return 0;
}
finally {
System.out.println("finally trumps return.");
}
}
输出:
finally trumps return.
0
此外,虽然这是不好的做法,如果在finally块中有一个return语句,它将胜过常规块中的任何其他返回。也就是说,以下块将返回false:
try { return true; } finally { return false; }
从finally块中抛出异常也是一样的。
这是Java语言规范中的官方文字。
14.20.2。执行try-finally和try-catch-finally
一个
try
声明与finally
块首先执行try
块。然后有一个选择:
- 如果执行了
try
块正常完成,[...]- 如果执行了
try
由于a,块突然完成throw
一个价值 V,[...]- 如果执行了
try
由于任何其他原因,块突然完成 [R那么finally
块被执行。然后有一个选择:
- 如果finally块正常完成,那么
try
声明突然完成了 [R。- 如果
finally
阻止突然完成的原因 小号那么try
声明突然完成了 小号 (和原因 [R 被丢弃了)。
规范 return
实际上这是明确的:
ReturnStatement: return Expression(opt) ;
一个
return
声明没有Expression
尝试 将控制转移到包含它的方法或构造函数的调用者。一个
return
声明与Expression
尝试 将控制权转移给包含它的方法的调用者;的价值Expression
成为方法调用的值。前面的描述说“尝试 转移控制“而不仅仅是”转移控制“因为如果有的话
try
方法或构造函数中的语句try
块包含return
声明,然后任何finally
那些条款try
在将控制权转移给方法或构造函数的调用者之前,将按顺序执行语句,从最里面到最外层。突然完成一个finally
条款可以破坏由a发起的控制权转移return
声明。
除了其他响应之外,重要的是要指出'finally'有权通过try..catch块覆盖任何异常/返回值。例如,以下代码返回12:
public static int getMonthsInYear() {
try {
return 10;
}
finally {
return 12;
}
}
同样,以下方法不会抛出异常:
public static int getMonthsInYear() {
try {
throw new RuntimeException();
}
finally {
return 12;
}
}
虽然以下方法确实抛出它:
public static int getMonthsInYear() {
try {
return 12;
}
finally {
throw new RuntimeException();
}
}
我尝试了上面的例子,略有修改 -
public static void main(final String[] args) {
System.out.println(test());
}
public static int test() {
int i = 0;
try {
i = 2;
return i;
} finally {
i = 12;
System.out.println("finally trumps return.");
}
}
上面的代码输出:
最后胜过回归。
2
这是因为什么时候 return i;
被执行 i
有一个值2.在此之后 finally
执行块,其中12被分配给 i
接着 System.out
out已执行。
执行后 finally
阻止 try
block返回2,而不是返回12,因为这个return语句不会再次执行。
如果您将在Eclipse中调试此代码,那么您将在执行后感觉到 System.out
的 finally
阻止 return
声明 try
块再次执行。但这种情况并非如此。它只返回值2。
这是一个详细说明 凯文的回答。重要的是要知道之前要评估要返回的表达式 finally
,即使之后归还。
public static void main(String[] args) {
System.out.println(Test.test());
}
public static int printX() {
System.out.println("X");
return 0;
}
public static int test() {
try {
return printX();
}
finally {
System.out.println("finally trumps return... sort of");
}
}
输出:
X
finally trumps return... sort of
0
这就是最终块的整体想法。它允许您确保进行清理,否则可能会因为您返回而被忽略,当然。
终于被召唤了 不管发生了什么 在try块中(除非 你打电话 System.exit(int)
或Java虚拟机因其他原因而踢出)。
考虑这一点的合理方式是: