显式抛出的异常是否向上抛出?



免责声明:我无法访问Java编译器,也无法安装IDE,我的工作区没有给我足够的权限。

我试图了解Java如何处理异常,并偶然发现了这个问题:

如果子类在捕获所有异常的 catch 块中显式抛出异常,它是否会引发?例如,请考虑以下代码行:

public Class someClass  {
public int value;
public someClass()  {
value = 1;
try {
value ++;
if(value == 2)  {
throw new Exception("value is 2");
}
}   catch   (exception e)   {
System.out.println("I caught an exception.");
throw new Exception("Does this exception get thrown upwards?");
System.out.println("will this line of code get printed after the previously thrown exception?");
}   finally {
return;
}
}
}
public class anotherClass   {
public static void main throws Exception{
someClass someclass = new someClass();  // will this class catch the second explicitly thrown exception?
}
}

因此,在try块中抛出一个新的异常,由以下捕获块捕获。第二个抛出语句去哪儿了?如果有的话,它是否会向上进入调用类?另外,println 语句是否会在引发异常后执行,即使它不在 finally 块中?

谢谢。

第二个抛出语句去哪儿了?它是否向上进入 如果有的话,叫类?

是的,异常将被抛出到调用方方法,在您的情况下,它是main()方法。

抛出异常后,println 语句是否会被执行 即使它不在最终块中?

是的,System.out.println("I caught an exception.")将被执行,然后将 Exception 对象抛给调用方(即main()),因此在您的 catch 块中,无法访问以下行。

System.out.println("will this line of code get 
printed after the previously thrown exception?");

重要的一点是,您始终可以使用exception.printStackTrace()(在catch块内)来检查异常是如何在方法堆栈中传播的。我建议您尝试此操作,以便清楚地看到异常是如何跨方法传播的。

我建议你参考这里并清楚地了解方法链是如何执行的。

此外,您可能感兴趣的另一点是,当main()方法抛出异常(即,main()本身或通过链,无论如何),JVM 会捕获异常并关闭

尽管可能不是故意的,但在该特定情况下不会引发异常,您也可以通过someClass构造函数中缺少的throws子句看到这一点。

原因是finally块中的return语句,导致 java 丢弃异常(并且一个好的 IDE 会给你一个"finally 块无法正常完成"警告)。

更具体地说,规范的第 14.20.2 节指出:

如果 catch 块由于原因 R 而突然完成,则最终 块被执行。然后有一个选择:

  • 如果 finally 块正常完成,则 try 语句由于原因 R 而突然完成。

  • 如果 finally 块由于原因 S 而突然完成
  • ,则 try 语句由于原因 S 而突然完成(并且原因 R 被丢弃)。

原因 Sreturn陈述,原因 Rthrow new Exception("Does this exception get thrown upwards?");

您可以在 ideone.com 上看到自己:

class someClass {
public int value;
public someClass() {
value = 1;
try {
value++;
if (value == 2) {
throw new Exception("value is 2");
}
} catch (Exception e) {
System.out.println("I caught an exception.");
throw new Exception("Does this exception get thrown upwards?");
} finally {
return;
}
}
}
class anotherClass {
public static void main(String[] args) {
try {
someClass someclass = new someClass(); 
} catch (Exception e) {
e.printStackTrace();
}
}
}

输出:

I caught an exception.

但就这个问题的目的而言,javaguy的回答已经很好地涵盖了一般观点。

最新更新