我有两个问题:
答案 0 :(得分:8)
在这两种情况下,都是因为你覆盖的基本方法已经设置了与调用代码的契约;如果您可以添加该方法可能抛出的已检查异常,那么您将违反合同。
考虑使用方法Base
的类foo
,该方法会抛出已检查的异常SomeException
。您还有Derived
,其源自Base
并覆盖foo
。 App
中的代码使用Base b
变量,但使用Derived
的新实例进行初始化,并调用b.foo()
。合同是foo
只抛出SomeException
;抛出任何其他东西都违反了合同。
答案 1 :(得分:2)
重写类可以添加行为而不是删除。声明抛出异常的方法是一种行为。
如果您有课程A
和B extends A
,请考虑会发生什么。
A
实施foo() throws MyException
,B
实施foo() throws OtherException
会是什么
A a = new B();
a.foo();
必须赶上?
但是,如果B.foo()
仅抛出异常的一部分 - 它仍然非常安全,则调用环境将捕获(或声明为抛出)所有A
抛出的异常 - 并且这样做 - 它也将处理所有B的。
答案 2 :(得分:2)
答案 3 :(得分:2)
让我们说可以在重写方法中添加新的抛出异常。
class AA{
void method() throws FileNotFoundException{}
}
class BB extends AA{
@Override
void method() throws FileNotFoundException, UnsupportedEncodingException {}
}
现在您为对象BB创建引用AA并调用方法
AA a=new BB();
try {
a.method();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Compilator将只允许您捕获FileNotFoundException
异常,并且不会允许捕获UnsupportedEncodingException
,因为它是从参考AA调用的。
但是你可以为重写方法添加几种类型的例外
IOException
- > IOException, FileNotFoundException
),因为它们会被检查,RuntimeException
s