方法重写、继承和异常

4

子类中的一个方法可以覆盖父类中的一个方法,并在父类方法没有抛出异常时抛出运行时异常吗?就像这样:

class X { public void foo() { System.out.print("X "); } }

public class SubB extends X {
    public void foo() throws RuntimeException {
        super.foo();
        if (true) 
            throw new RuntimeException();
        System.out.print("B ");
    }

    public static void main(String[] args) {
        new SubB().foo();
    }
}
1个回答

3
是的,因为运行时异常不是方法签名的一部分。(您可以添加它们,但编译器并不关心它们,它们只是文档。)
我认为这样做的原因是RuntimeException通常是程序员错误,例如NPE或者越界访问数组,所以尝试限制它们的方式就像检查异常被限制那样没有意义。您不能规定说,这个方法(和任何覆盖它的方法)永远不会抛出NullPointerException,因为JVM不会给出这些保证。
在Java语言规范中,在“Compile-Time Checking of Exceptions”下面,它说:
未经检查的异常类(§11.1.1)免于编译时检查。 在未经检查的异常类中,错误类免除了这种检查,因为它们可能会在程序的许多点发生,并且从中恢复很难或者不可能。声明这些异常的程序将变得混乱和毫无意义。高级程序仍然希望捕获并尝试从其中一些条件中恢复过来。
在未检查的异常类中,运行时异常类免除此类检查,因为按照Java编程语言的设计者的判断,声明这样的异常不会在建立程序的正确性方面有很大帮助。Java编程语言的许多操作和结构可能导致运行时异常。对于Java编译器可用的信息以及编译器执行的分析级别,通常不足以确定此类运行时异常不可能发生,即使这对程序员来说是显而易见的。要求声明此类异常类将仅对程序员造成困扰。
例如,某些代码可能会实现一个循环数据结构,该结构可以通过构造方式永远不涉及空引用;程序员可以确信NullPointerException不会发生,但是Java编译器很难证明它。建立这些数据结构的全局属性所需的定理证明技术超出了本规范的范围。

但是,如果覆盖方法不应该抛出更严格的异常呢? - praxmon
4
这仅适用于已检查异常。 - Louis Wasserman
因为运行时异常不被检查,所以没问题,对吧?谢谢! - praxmon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接