0

我正在阅读从构造函数中抛出异常的主题。在通过 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){

  }
} 

我在子类中提供了一个无参数构造函数,它会引发更广泛的异常。当我重载构造函数时,它说我没有处理检查的异常。所以这意味着我们不能在不抛出相同或更广泛的检查异常的情况下启动子类?有人可以解释一下吗。本

4

4 回答 4

7

那么每个子类将链接到一个超类构造函数。在您的情况下,这是隐式发生的-例如:

public TestConstructorException(int x) {
}

相当于

public TestConstructorException(int x) {
  super();
}

您无法在子类构造函数中捕获该超类构造函数引发的任何异常,因为与超类构造函数的链接必须是构造函数主体中的第一件事——您甚至无法启动一个try块。

那么,如果超类构造函数抛出异常,你希望你的子类构造函数做什么?

于 2013-07-17T20:08:09.880 回答
1

您必须在子类构造函数中声明相同的异常,或者至少声明一个更广泛的异常,因为超类构造函数仅由子类构造函数调用,在对象创建过程中,在super()调用的帮助下。要么你明确地给出它,要么编译器为你添加它作为你所有构造函数中的第一条语句。

所以,如果父类构造函数抛出异常,就会抛出给子类构造函数。但是您不能使用try-catch围绕super()调用的块来处理异常,因为它super()必须是构造函数中的第一条语句。这就是为什么编译器将其标记为编译时错误,如果它没有看到声明为抛出的异常。

于 2013-07-17T20:08:42.907 回答
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{

 }
于 2013-07-17T20:12:59.427 回答
0

Super class constructor (super())声明它的异常,所以它留给调用者,即subclass constructor. 子类构造函数声明(通过 throws)或super()try-catch.

如果没有添加到方法签名中,编译器会提示“将异常添加到方法签名中”。

如果super()在内部调用try-catch,编译器会抱怨“调用 'super()' 必须是构造函数主体中的第一条语句”。第二个选项不是未处理异常的解决方案。

于 2022-01-30T06:08:09.077 回答