我认为如果您使用更有意义的异常名称,您可能会更清楚,因为您的异常命名并不能反映异常的真正目的。
例如,假设您的Exception1
is now IOException
。这表明存在一些输入输出问题。而您的扩展异常,而不是Exception2
现在称为FileNotFoundException
. 它表示特定的输入输出错误 - 未找到文件。
所以,如您所见, aFileNotFoundException
是一种IOException
. 这就是这个词extends
定义的关系。
现在想象一下,如果你的方法被声明:
public void invokeValidation() throws FileNotFoundException {
obj1.method(); // it throws IOException
obj2.method(); // it throws FileNotfoundException
}
所以,你说“我的方法抛出了一个FileNotFoundException
”。编译器知道如果它遇到这个特定的异常,它应该把它扔给调用者。但obj1
可能会抛出一个IOException
. 这可能是一个异常,表明磁盘上没有空间。或者说有坏块。或者文件被突然关闭。这可能是很多事情。一个IOException
不是一个。_ FileNotFoundException
因此,编译器与它没有任何关系,它告诉你这是一个未处理的异常。
但是如果你的方法被声明:
public void invokeValidation() throws IOException {
obj1.method(); // it throws IOException
obj2.method(); // it throws FileNotfoundException
}
编译器不会抱怨。为什么?因为 for obj1
,它会抛出一个IOException
,这很好,它就在标题中,可以向上抛出一个级别。而对于obj2
,它知道这FileNotFoundException
是一个(type of) IOException
,因此它被允许抛出它。它是多态的IOException
,调用者将知道如何处理它。
所以继承的层次很重要。如果你有两个方法抛出两个异常,一个是另一个的超类,你应该声明你的方法来抛出超类。因为任何子类与超类都有“is_A”关系。它是超类的一种特殊类型。但反过来是不正确的。