从构造函数中抛出异常 - 是否必须抛出子类?

时间:2013-07-17 20:05:35

标签: java

我正在阅读从构造函数中抛出异常的主题。在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构造函数,它抛出了一个更广泛的异常。 当我重载构造函数时,它说我没有处理检查的异常。所以这意味着 我们不能在没有抛出相同或者相同的已检查异常的情况下启动子类 更广泛?请有人解释一下。 本

3 个答案:

答案 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{

 }