Jub*_*uff 150 java exception-handling exception
关于大学的Java问题,有这段代码:
class MyExc1 extends Exception {}
class MyExc2 extends Exception {}
class MyExc3 extends MyExc2 {}
public class C1 {
public static void main(String[] args) throws Exception {
try {
System.out.print(1);
q();
}
catch (Exception i) {
throw new MyExc2();
}
finally {
System.out.print(2);
throw new MyExc1();
}
}
static void q() throws Exception {
try {
throw new MyExc1();
}
catch (Exception y) {
}
finally {
System.out.print(3);
throw new Exception();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我被要求提供输出.我回答13Exception in thread main MyExc2,但正确的答案是132Exception in thread main MyExc1.为什么会这样?我只是无法理解MyExc2在哪里.
Ber*_*t F 156
在阅读你的答案并了解你如何提出它的基础上,我相信你认为"正在进行中的异常"具有"优先权".记住:
当一个新的异常被抛出一个catch块或者最后一个将传播出该块的块时,当新的异常向外传播时,当前的异常将被中止(并被遗忘).新异常开始展开堆栈,就像任何其他异常一样,从当前块(catch或finally块)中止,并受到任何适用的catch或finally块的影响.
请注意,适用的catch或finally块包括:
当在catch块中抛出新异常时,新异常仍然受该catch的finally块(如果有)的影响.
现在回溯执行,记住每当你点击时throw,你应该中止跟踪当前的异常并开始跟踪新的异常.
Buh*_*ndi 38
这就是维基百科关于finally子句的说法:
更常见的是一个相关的条款是否发生了异常,通常以释放异常处理块的主体内获得的资源时执行(最终,或确保).
让我们剖析您的计划.
try {
System.out.print(1);
q();
}
Run Code Online (Sandbox Code Playgroud)
因此,1将被输出到屏幕,然后q()被调用.在q(),抛出异常.然后捕获异常,Exception y但它什么也没做.甲最后然后子句被执行(它有),所以,3将被打印到屏幕.因为(在方法q()中,finally子句中抛出异常,也会q()将异常传递给父堆栈(通过throws Exception方法声明中)new Exception()将被抛出并被捕获catch ( Exception i ),MyExc2异常将被抛出(现在将其添加到异常堆栈中) ),但最后在main块中将首先执行.
所以,在
catch ( Exception i ) {
throw( new MyExc2() );
}
finally {
System.out.print(2);
throw( new MyExc1() );
}
Run Code Online (Sandbox Code Playgroud)
一个finally子句被称为...(记住,我们刚刚捕获Exception i并抛出MyExc2)本质上2是打印在屏幕上...并且2在屏幕上打印之后,MyExc1抛出异常.MyExc1由public static void main(...)方法处理.
输出:
"线程主MyExc1中的132Exception"
讲师是对的!:-)
从本质上说,如果你有一个最终在一个try/catch子句,终于将(执行后捕获异常之前抛出捕获的异常出)
Rol*_*and 33
引自JLS 11:14.20.2.执行try-finally和try-catch-finally
如果catch块由于原因R突然完成,则执行finally块.然后有一个选择:
如果finally块正常完成,则try语句突然完成,原因是R.
如果finally块由于原因S而突然完成,则try语句突然完成,原因S(并且原因R被丢弃).
Ale*_*yak 21
即使从try/catch块中的任何地方抛出异常,也会执行finally子句.
因为它是最后一个被执行main并且它抛出异常,这是调用者看到的异常.
因此,确保该finally子句不会抛出任何东西的重要性,因为它可以吞噬try块中的异常.
A method不能同时有throw两个例外.它将始终抛出最后一次抛出exception,在这种情况下,它将始终是finally块中的一个.
当q()抛出方法的第一个异常时,它会被finally块抛出异常捕获然后吞噬.
q()- >抛出new Exception - > main catch Exception - > throw new Exception - > finally抛出一个新的exception(和catch"丢失"中的一个)
直到打印出来逻辑才清晰13。然后in抛出的异常q()被catch (Exception i)in捕获main()并且anew MyEx2()准备好抛出。但是,在抛出异常之前,finally必须先执行该块。然后输出变为132并finally要求抛出另一个异常new MyEx1()。
由于一个方法不能抛出多个异常Exception,因此它总是会抛出最新的异常Exception。换句话说,如果 和catch块finally都尝试抛出Exception,则Exceptionin catch 会被吞掉finally,并且只会抛出 in 的异常。
因此,在这个程序中,ExceptionMyEx2被吞掉并被MyEx1抛出。这个异常被抛出main()并且不再被捕获,因此JVM停止并且最终的输出是132Exception in thread main MyExc1.
finally本质上,如果在子句中有 a try/catch,则 a将在捕获异常之后但在抛出任何捕获的异常之前finally执行,并且最后只会抛出最新的异常。