我正在用Java编写一个类,它是我编写的另一个类的子类,它的构造函数显式调用了超类的构造函数。超类的构造函数在直接初始化时可能抛出几种类型的异常,但是当我初始化我的子类的一个实例时,有几个异常永远不会被抛出(按设计)。
我尝试在子类的构造函数中捕获这些异常,但是我收到一条错误,指出“构造函数调用必须是构造函数中的第一个语句”。为什么我不能抓住这些例外?
例如,下面的代码:
public class Persian_Cat extends Cat {
public Persian_Cat(File file) {
try{
super(file);
} catch(InvalidArgumentException e) {
} catch(FileNotFoundException e) {
}
}
}
将语句super(file);
标记为错误。
如何实现子类构造函数,以便知道这些异常是无关紧要的?我需要这个,因为我不希望稍后在我的代码中为try {} ... catch {}包装此构造函数。
答案 0 :(得分:6)
遗憾的是,如果使用super(...);
,它必须是构造函数中的第一行代码。没有办法避免这种情况。
一种解决方案是创建另一个不会抛出这些异常的构造函数。将此范围视为受保护而非公开可能是明智的。您可能希望记录API,以明确哪些输入验证(或其他)由于哪些假设而未进行。
答案 1 :(得分:1)
如果您的第一行不是显式超级构造函数调用,那么JVM将插入一个空行。因此,如果您需要调用非空的超级构造函数,则必须成为第一行。
public Persian_Cat(File file) throws InvalidArgumentException,
FileNotFoundException {
super(file);
}
JLS-8.8.7读取(部分),
如果构造函数体不以显式构造函数调用开始,并且声明的构造函数不是原始类
Object
的一部分,则构造函数体隐式地以超类构造函数调用“super();”开头。 ,调用其直接超类的构造函数,不带参数。
所以当你问为什么我不能捕获这些异常?答案是Java没有提供这样做的机制。您可以将Persian_Cat
构造函数标记为抛出它们。或者您可以创建另一个不抛出异常或将文件设置器添加到超类型的构造函数。或许你需要一个建造者或工厂。