编译时异常检查.finally块隐式抛出未检查异常的情况



以下代码编译完美。我相信这是因为编译器在编译时知道控件将转到finally块并抛出未检查的异常(这是可以的,不需要处理),并且它知道在此之前代码抛出的所有其他异常都会丢失。所以不用担心他们。

try{
     // DoSomething();
}catch(Exception e){ 
     // Throw checked exception
}finally{
    // Throw unchecked exception
}

示例:

public class TestClass {
public static void main(String[] args) {
    TestClass c = new TestClass();
    try {
        // Whatever
    } catch (Exception e) {
        throw new FileNotFoundException(); 
    } finally {
        throw new NullPointerException();
    }
}
}

到目前为止还不错,直到我从一个方法中抛出未检查的异常

try{
     // DoSomething();
}catch(Exception e){ 
     // Call a method that throws a checked exception
     // or just throw the checked exception from here
}Finally{
    // Call a method that throw an unchecked exception
}

示例:

public class TestClass {
public static void main(String[] args) {
    TestClass c = new TestClass();
    try {
        //Whatever
    } catch (Exception e) {
         c.m1(); 
             // or just throw it here
             // throw new FileNotFoundException();
    } finally {
        c.m2();
    }
}
public void m1() throws IOException {
    throw new FileNotFoundException();
}
public void m2() throws RuntimeException {
    throw new NullPointerException();
}
}

此代码不会编译。它用错误"未处理的异常类型_"(eclipse)或"未报告的异常_;必须捕获或声明为抛出"(cmd)标记c.m1()。

就好像它忽略了finally块将抛出LAST异常(未选中),并且无需担心catch块中的那个异常,即使它是未处理的已选中异常,因为它们无论如何都会丢失!知道m2()被声明为专门抛出未检查的异常(RuntimeException)。

有人能更好地解释为什么第二段代码中出现编译错误吗?感谢:)

异常只是不会"抛出"它们自己。您必须显式处理被调用方法抛出的任何已检查异常——无论它们发生在哪里。您调用的任何引发已检查异常的对象都必须被try-catch块包围,或者调用子方法的方法必须声明以引发相同类型的异常。这不适用于已检查的异常。

这意味着,在你有的地方

catch (Exception e) {
     c.m1(); 
         // or just throw it here
         // throw new FileNotFoundException();
}

您必须捕获m1抛出的已检查异常,因为main没有声明它抛出任何东西。

在try/catch上有finally块的情况下,您仍然必须处理被调用方法抛出的任何已检查异常——即使是在catch块中。但是,如果您使用显式抛出运行时异常的finally块显式抛出已检查的异常,编译器会允许它,因为它可以确定事件的顺序——在任何情况下,在任何时间。

相关内容

  • 没有找到相关文章

最新更新