java - 在catch和最后claus中抛出异常
关于大学的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();
}
}
}
我被要求提供输出。 我回答了13Exception in thread main MyExc2,但正确答案是132Exception in thread main MyExc1.为什么? 我只是无法理解MyExc2在哪里。
10个解决方案
135 votes
在阅读你的答案并了解你如何提出它的基础上,我相信你认为“正在进行中的异常”具有“优先权”。 记住:
当一个新的异常被抛出一个catch块或者最后一个将传播出该块的块时,当新的异常向外传播时,当前的异常将被中止(并被遗忘)。 新异常开始展开堆栈,就像任何其他异常一样,从当前块(catch或finally块)中止并受到任何适用的catch或finally块的影响。
请注意,适用的catch或finally块包括:
当在catch块中抛出新异常时,新异常仍然受该catch的finally块(如果有)的影响。
现在回溯执行记住,每当你点击throw时,你应该中止跟踪当前异常并开始跟踪新异常。
Bert F answered 2019-05-28T07:49:58Z
35 votes
这就是维基百科关于finally子句的说法:
更常见的是相关条款 (最后,或确保)执行 是否发生异常, 通常是释放资源 在体内获得 异常处理块。
让我们剖析您的计划。
try {
System.out.print(1);
q();
}
因此,Exception i将输出到屏幕,然后调用MyExc2。 在2中,抛出异常。 然后由2捕获该异常,但它什么也没做。 然后执行finally子句(必须),因此,MyExc1将被打印到屏幕上。 因为(在方法MyExc1中,在finally子句中抛出异常,同样public static void main(...)方法将异常传递给父堆栈(由方法声明中的throws Exception)new Exception()将被抛出并被catch ( Exception i )捕获,MyExc2将抛出异常(暂时 将它添加到异常堆栈中),但最终将在main块中执行。
所以,在
catch ( Exception i ) {
throw( new MyExc2() );
}
finally {
System.out.print(2);
throw( new MyExc1() );
}
一个finally子句被称为...(记住,我们刚刚捕获Exception i并抛出MyExc2)本质上,2打印在屏幕上......并且在屏幕上打印2之后,抛出了MyExc1异常。 MyExc1由public static void main(...)方法处理。
输出:
“线程主MyExc1中的132Exception”
讲师是对的!:-)
本质上,如果你在try / catch子句中有一个finally,则会执行finally(在捕获异常之后抛出捕获的异常)
Buhake Sindi answered 2019-05-28T07:51:37Z
28 votes
引自JLS 11:14.20.2。 执行try-finally和try-catch-finally
如果catch块因为R而突然完成,那么最后 块被执行。 然后有一个选择:
如果finally块正常完成,则try语句突然完成,原因是R.
如果finally块由于原因S而突然完成,则try语句突然完成,原因S(并且原因R被丢弃)。
Roland answered 2019-05-28T07:52:21Z
19 votes
即使从try / catch块中的任何地方抛出异常,也会执行finally子句。
因为它是在finally中执行的最后一个并且它抛出异常,这是调用者看到的异常。
因此,确保finally子句不会抛出任何内容的重要性,因为它可以吞噬try块中的异常。
Alexander Pogrebnyak answered 2019-05-28T07:53:12Z
7 votes
A new Exception不能同时有两个例外main。 它将始终抛出最后抛出的catch Exception,在这种情况下,它将始终是throw块中的一个。
当抛出方法new Exception的第一个异常时,它将被finally块抛出异常捕获然后吞噬。
q() - > 抛出new Exception - > main catch Exception - > throw new Exception - > finally抛出一个新的exception(并且catch中的一个被“丢失”)
Garis M Suero answered 2019-05-28T07:54:04Z
2 votes
想到这一点的最简单方法是想象整个应用程序中存在一个变量全局变量,它保存当前异常。
Exception currentException = null;
抛出每个异常时,“currentException”被设置为该异常。 当应用程序结束时,如果currentException是!= null,则运行时报告错误。
此外,finally块始终在方法退出之前运行。 然后,您可以将代码段重新命名为:
public class C1 {
public static void main(String [] argv) 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() ); //
}
}
}
应用程序执行的顺序是:
main()
{
try
q()
{
try
catch
finally
}
catch
finally
}
CodingWithSpike answered 2019-05-28T07:55:01Z
1 votes
众所周知,finally块在try和catch之后执行并且始终执行....但是正如你所看到的那样有点棘手,有时会查看下面的代码片段,你会那样做return和throw语句并不总是按照我们期望主题的顺序执行它们应该执行的操作。
干杯。
/Return dont always return///
try{
return "In Try";
}
finally{
return "In Finally";
}
while(true) {
try {
return "In try";
}
finally{
break;
}
}
return "Out of try";
///
///
while (true) {
try {
return "In try";
}
finally {
continue;
}
}
//
/Throw dont always throw/
try {
throw new RuntimeException();
}
finally {
return "Ouuuups no throw!";
}
//
Sly answered 2019-05-28T07:55:40Z
0 votes
我想你只需要走finally块:
打印“1”。
finally in main打印“3”。
finally in main打印“2”。
Uwe Keim answered 2019-05-28T07:56:34Z
0 votes
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("TryA L1\n");
q();
System.out.print("TryB L1\n");
}
catch (Exception i) {
System.out.print("Catch L1\n");
}
finally {
System.out.print("Finally L1\n");
throw new MyExc1();
}
}
static void q() throws Exception {
try {
System.out.print("TryA L2\n");
q2();
System.out.print("TryB L2\n");
}
catch (Exception y) {
System.out.print("Catch L2\n");
throw new MyExc2();
}
finally {
System.out.print("Finally L2\n");
throw new Exception();
}
}
static void q2() throws Exception {
throw new MyExc1();
}
}
订购:
TryA L1
TryA L2
Catch L2
Finally L2
Catch L1
Finally L1
Exception in thread "main" MyExc1 at C1.main(C1.java:30)
[https://www.compilejava.net/]
Luiz Fernando answered 2019-05-28T07:57:15Z
-1 votes
我认为这解决了这个问题:
boolean allOk = false;
try{
q();
allOk = true;
} finally {
try {
is.close();
} catch (Exception e) {
if(allOk) {
throw new SomeException(e);
}
}
}
Vouze answered 2019-05-28T07:57:48Z