我正在阅读从构造函数中抛出异常的主题。在stackflow上研究了一些相同的主题之后。我得出的结论是,我们可以从构造函数中抛出异常。当我们尝试子类化其构造函数抛出异常的父类时,就会出现问题。例如,请参阅下面的以下代码段。
class ParentConstructorException{
public ParentConstructorException() throws IOException {
}
}
public class TestConstructorException extends ParentConstructorException {
public TestConstructorException() throws Exception{
}
//Causes compile time error if i don't throw exception
public TestConstructorException(int x){
}
}
我在子类中提供了一个no-arg构造函数,它抛出了一个更广泛的异常。 当我重载构造函数时,它说我没有处理检查的异常。所以这意味着 我们不能在没有抛出相同或者相同的已检查异常的情况下启动子类 更广泛?请有人解释一下。 本
答案 0 :(得分:7)
每个子类都链接到一个超类构造函数。在你的情况下,这是隐含发生的 - 例如:
public TestConstructorException(int x) {
}
相当于
public TestConstructorException(int x) {
super();
}
你不能捕获子类构造函数中超类构造函数抛出的任何异常,因为超类构造函数的链接必须是构造函数体中的第一件事 - 你甚至无法启动try
块
那么,如果超类构造函数引发异常,那么你希望期望你的子类构造函数会做什么?
答案 1 :(得分:1)
您必须在子类构造函数中声明相同的异常,或至少更宽泛的异常,因为超级构造函数仅在子类构造函数的调用下,在创建对象的过程中,借助{{ 1}}打电话。要么明确地给它,要么编译器为你添加它作为所有构造函数中的第一个语句。
因此,如果父类构造函数抛出异常,它将抛出到子类构造函数。但你不能使用围绕super()
调用的try-catch
块来处理异常,因为super()
必须是构造函数中的第一个语句。这就是为什么编译器将它标记为编译时错误,如果它没有看到声明被抛出的异常。
答案 2 :(得分:1)
当我重载构造函数时,它表示我没有处理检查 例外。所以这意味着我们不能在没有的情况下启动子类 抛出相同或更广泛的已检查异常?
您无法处理在执行子类之前调用super()
的异常。
public TestConstructorException(int x){
super(); // this throws IOException , and it's a checkedException so this won't compile
}
如果您尝试try-catch
怎么办?
这不会编译。因为你不能这样做。在第一个语句
中调用 super()public TestConstructorException(int x){
try{
super(); // this throws IOException
}catch(IOException e){
//do something
}
所以你必须扔掉
public TestConstructorException(int x) throws IOException{
}