繁体   English   中英

为什么会这样编译? 覆盖方法不是异常的子类

[英]Why does this compile? Overriding method not a subclass of exception

我很难理解为什么以下代码可以编译,而它不是异常的子类:

class Test 
{
    public void run() throws IOException 
    {
        System.out.println("Test");
    }
}

class SubTest extends Test 
{
    //not a subclass of IOException, still compiles 
    public void run() throws RuntimeException 
    {
        System.out.println("Test from sub");
    }
}

class Sub2Test extends Test 
{
    //not a subclass of IOException, does not compile
    public void run() throws Exception  
    {
        System.out.println("Test from sub");
    }
}

我知道RuntimeException是一个未经检查的异常,但我认为规则是它必须是父异常的子类?

想象有一个调用者调用Test#run Test#run的声明中,它说它可能会抛出IOException ,因此调用者知道它可以捕获并处理它:

Test test = // it could be instance of SubTest of Sub2Test
try {
   test.run();
} catch (IOException e) {

}

那么如果SubTest不抛出IOException就可以了,调用者不会错过任何东西。

但是如果你抛出一些像Sub2Test这样的已检查Exception ,由于调用者直到运行时才知道它,所以被调用者无法捕获和处理它。 所以不应该编译。

“我理解 RuntimeException 是一个未经检查的异常,但我认为规则是它必须是父异常的子类?”

这是 JLS 第11.2 节中规定的一般规则。 Compile-Time Checking of Exceptions ,其中指出(强调我的)

覆盖方法的 throws 子句可能未指定此方法将导致抛出任何已检查的异常,而覆盖方法的 throws 子句不允许抛出该异常(第8.4.8.3 节)。

但这仅适用于受检查的异常,并且它还明确指出

未经检查的异常类( §11.1.1 )免于编译时检查。

所以编译器会忽略RuntimeException不是IOException的子类的事实。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM