有谁知道为什么对于重写过程,重写方法必须抛出与重写方法相同类型(或子类型)的异常,而另一方面,对于构造函数,它以相反的方式工作(因此,必须抛出相同的异常或超类抛出的超类型。提前非常感谢。
3 回答
构造函数不会覆盖其超类的构造函数,但它们会显式或隐式调用超类的构造函数。因此,就像调用某个抛出 的其他方法的方法一样Exception
,构造函数必须要么捕获超类的构造函数抛出的异常,要么必须声明它抛出相同的异常(或该异常的超类)。
另一方面,重写方法必须遵守超类的方法定义。因此,它可以抛出更具体的异常或根本不抛出异常。但它不能抛出更广泛的异常,因为这会违反超类的合同。
我相信子类构造函数没有这样的限制。他们可以抛出他们关心的任何类型的异常,与超类构造函数抛出的类型无关。显然,如果他们让来自超类构造函数的异常通过,他们将不得不声明它或它的超类型,就像使用任何其他方法一样。但是,这并不是对子类构造函数的特定限制:您可以通过抛出其他类型来轻松捕获和处理异常。
原因是子类中的构造函数不会“覆盖”超类中的构造函数,并且不会以多态方式使用。这是一个独立的东西,就像一个被调用Subclass.B()
的函数独立于Superclass.A()
.
此外,您始终知道,当您调用 时new Subclass()
,您正在调用该构造函数。然而,如果您引用 aSuperclass
并调用superclass.overriddenMethod()
它,您无法确定类型是什么。因此,任何重写该方法的子类都不能抛出除了在超类上声明的异常之外的异常,就像它们可以更改方法签名的其余部分一样。
在构造函数中总是有一个(可能是隐式的)对 super 的调用。抛出一个超类 Exception 也会捕捉到这一点。
public B() {
... initialize fields declared with X x = ...;
... call super constructor
... body of constructor
}
An overriding method however can be more specific, also for the exceptions: reduce the possibilities.