java 什么是最先出现的 - finally 还是 catch 块?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3109353/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What comes first - finally or catch block?
提问by Yuval Adam
Consider the following test case:
考虑以下测试用例:
public class Main {
static int a = 0;
public static void main(String[] args) {
try {
test();
System.out.println("---");
test2();
}
catch(Exception e) {
System.out.println(a + ": outer catch");
a++;
}
}
public static void test()
{
try {
throw new Exception();
}
catch (Exception e) {
System.out.println(a + ": inner catch");
a++;
}
finally {
System.out.println(a + ": finally");
a++;
}
}
public static void test2() throws Exception
{
try {
throw new Exception();
}
finally {
System.out.println(a + ": finally");
a++;
}
}
}
With output:
有输出:
0: inner catch
1: finally
---
2: finally
3: outer catch
What's the explanation for why in test()catch happens before finally while in test2()it's the other way around?
为什么 in test()catch 发生在 finally 之前,而 in test2()it 是相反的解释?
采纳答案by BalusC
Because the tryblock in test2()doesn't have a catchblock, only a finally. The code won't "jump back" to the caller to fall into catchand then "jump ahead" to the finallyto continue there as you seem to think.
因为try块 intest2()没有catch块,只有一个finally. 代码不会像您认为的那样“跳回”调用者catch,然后“跳回”到finally那里继续。
回答by polygenelubricants
The key points are these:
关键点是这些:
- In a
try-(catch)-finallyblock, thefinallyfor that particulartryblock is performed last - You can nest
tryblocks within another, and each of those nestedtryblocks can have their ownfinally, which would be performed last for those individualtryblocks
- 在一个
try-(catch)-finally块中,最后执行finally该特定try块的 - 您可以将块嵌套
try在另一个块中,并且每个嵌套try块都可以有自己的finally,这将在这些单独的try块中最后执行
So yes, finallyis performed last, but onlyfor the tryblock it's attached to.
所以是的,finally最后执行,但仅适用于try它所连接的块。
So given the following snippet:
因此,给出以下代码段:
try {
try {
throw null;
} finally {
System.out.println("Finally (inner)");
}
} catch (Throwable e) {
System.out.println("Catch (outer)");
}
This prints (as seen on ideone.com):
这打印(如在 ideone.com 上看到的):
Finally (inner)
Catch (outer)
Observe that:
请注意:
- Within
(inner),Finallyis last (whether or not anycatchwas successful) Catch (outer)followsFinally (inner), but that's becauseFinally (inner)is nested inside anothertryblock within(outer)
- 内
(inner),Finallyis last (不管有没有catch成功) Catch (outer)跟随Finally (inner),但那是因为Finally (inner)嵌套在另一个try块中(outer)
Similarly, the following snippet:
同样,以下代码段:
try {
try {
throw null;
} catch (Throwable e) {
System.out.println("Catch (inner)");
} finally {
System.out.println("Finally (inner)");
throw null;
}
} catch (Throwable e) {
System.out.println("Catch (outer)");
}
This prints (as seen on ideone.com):
这打印(如在 ideone.com 上看到的):
Catch (inner)
Finally (inner)
Catch (outer)
References
参考
Related questions
相关问题
回答by Peter Tillemans
catch comes before finally in the same try-catch-finally scope.
在同一个 try-catch-finally 范围内, catch 出现在 finally 之前。
It test2 there is no catch in the try-catch-finally scope of test2 so it does the finally before leaving the scope and falling in the higher catch.
它 test2 在 test2 的 try-catch-finally 范围内没有捕获,因此它在离开范围并落入更高的捕获之前执行 finally。
回答by Péter T?r?k
Because the finallyblock is always executed right before exiting scope. The sequence of events after calling test2()is as follows:
因为finally块总是在退出作用域之前执行。调用后的事件顺序test2()如下:
- exception is thrown in
test2() - Since
test2has nocatchblock, the exception is propagated up to the caller. - Since
test2has afinallyblock, it gets executed before returning from the method. - the
catchin the main method catches the exception.
- 异常被抛出
test2() - 由于
test2没有catch块,异常被传播到调用者。 - 由于
test2有一个finally块,它在从方法返回之前被执行。 - 该
catch在主方法捕捉异常。
回答by Adrian Regan
Because, finallyis the very last code to execute in a try..catch block, regardless of whether an exception was thrown, thrown and then handled, or not thrown at all.
因为,finally是在 try..catch 块中执行的最后一段代码,无论是抛出异常、抛出然后处理还是根本不抛出异常。
In fact the only time finally will notbe called is if the JVM exits before it gets to execute it, or if the thread that is executing the try code is killed or interrupted.
事实上,finally 唯一不会被调用的情况是JVM 在它开始执行之前退出,或者正在执行try 代码的线程被杀死或中断。
In response to comments: Java Description of finally
回复评论: finally的Java描述
Note: If the JVM exits while the try or catch code is being executed,then the finally block may not execute. Likewise, if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.
Note: If the JVM exits while the try or catch code is being executed,那么 finally 块可能不会执行。同样,如果执行 try 或 catch 代码的线程被中断或终止,即使应用程序作为一个整体继续运行,finally 块也可能不会执行。
However you are right that a ThreadDeath exception is thrown and I can't find much on the specifics of what seems to be conflicting information from sun. It could be a question in itself.
但是,抛出 ThreadDeath 异常是对的,而且我找不到很多关于来自 sun 的信息似乎有冲突的细节。这本身就可能是一个问题。
finally(pardon the pun) @brainimus, if you are in the finally and you throw an exception, then the finally code isbeing executed, my point was the conditions under which the finally code does not get executed.
最后(原谅双关语)@brainimus,如果你是在最后,你抛出一个异常,那么最后的代码被执行,我指的是在其下最后的代码没有得到执行的条件。
回答by Pragnesh Modh
try - catch and finally are used for avoiding situations when a program may get terminated due to the occurance of unwanted error during the execution of the program.
try - catch 和 finally 用于避免由于在程序执行过程中出现不需要的错误而导致程序终止的情况。
The following points are important....
以下几点很重要......
1)There is only one try for a block......any number of catch statements for a block and only one finally for a block of statments
1)一个块只有一次try......一个块可以有任意数量的catch语句,而一个语句块只有一个finally
2)finally is optional.
2)finally 是可选的。
3) catch is also optional but if the catch statement is missing then finally must appear.
3) catch 也是可选的,但如果缺少 catch 语句,则必须出现 finally。
4) All catches corresponding to the child exceptions must be appearing before a catch for a parent exception..
4) 与子异常对应的所有捕获必须出现在父异常的捕获之前。
5) Irrespective of the occurance of the exception the statements present in the finally block are executed always with one exclusion.
5) 不管异常是否发生,finally 块中的语句总是以一个排除执行。
i.e. IF a System.out.exit() statement is encountered then the program terminates imediately hence finally can not be executed in such cases.
即如果遇到 System.out.exit() 语句,则程序立即终止,因此在这种情况下最终无法执行。
Note: even there is an return statement appears in try block ...then also the code in finally is executed.
注意:即使在 try 块中出现了 return 语句......然后也会执行 finally 中的代码。
回答by Imdad Soomro
Try block is executed first. Catch is executed if there is an exception in try block that needs to be caught. Finally block runs in both the cases whether there is exception or not. If there is return statement inside try block then before returning in try block, finally block gets executed and then return is executed in try block.
Try 块首先执行。如果 try 块中存在需要捕获的异常,则执行 Catch。无论是否有异常,finally 块都会在这两种情况下运行。如果 try 块中存在 return 语句,则在 try 块中返回之前,将执行 finally 块,然后在 try 块中执行 return。
回答by Pierre Gardin
If you replace the functions by the methods' code you get:
如果你用方法的代码替换函数,你会得到:
public class Main {
static int a = 0;
public static void main(String[] args) {
try {
try {
throw new Exception();
}
catch (Exception e) {
// I catch only the *first* exception thrown
System.out.println(a + ": inner catch");
a++;
// let's go to the finally block
}
finally {
System.out.println(a + ": finally");
a++;
// we go on
}
System.out.println("---");
try {
throw new Exception();
}
finally {
// executed because at the same level
System.out.println(a + ": finally");
a++;
}
}
catch(Exception e) {
// I catch only the *second* exception thrown
System.out.println(a + ": outer catch");
a++;
}
}
The first exception makes the catch block execute, then the first finally block is executed. It is not visible at the outer level because of the first catch block. The second exception is intercepted by the catch block at the outer level, but the finally, located at the inner level, is executed first.
第一个异常使 catch 块执行,然后执行第一个 finally 块。由于第一个 catch 块,它在外层不可见。第二个异常被外层的catch块拦截,但是位于内层的finally首先被执行。

