如何将错误捕获留给子类?

mel*_*isa 1 java java-ee-8

public class First {
protected void method1() throws CustomException {
    int number=10/0;
    System.out.println("method 1" + number);
    throw new CustomException("Divided by zero");
}
public class Second extends First {
protected void method2() {
        method1();
    
}
public class Third extends Second {
protected void method3(){
    try {
        method2();
        }
        catch (CustomException ex)
        {
            System.out.println("Caught the exception");
            System.out.println(ex.getMessage());
        } 
}
Run Code Online (Sandbox Code Playgroud)

在这段代码中,首先抛出一个异常,我想从第三个捕获它(第二个不会处理错误)。但是第二个方法调用不会让我通过。我怎样才能解决这个问题?

Scr*_*tte 8

对于已检查的异常(不是任何RuntimeException),它们必须由调用另一个抛出异常的方法的方法处理或抛出。这也在 Oracle on Exceptions教程中进行了更深入的解释。

此示例基于您的代码:

class Testing{
  public static void main(String[] args) {
    Third t = new Third();
    t.method3();
  }
}
Run Code Online (Sandbox Code Playgroud)

它会打印:

Caught the exception
Divided by zero
Run Code Online (Sandbox Code Playgroud)

添加了缺少的实现CustomException

Caught the exception
Divided by zero
Run Code Online (Sandbox Code Playgroud)

请注意,您的代码永远不会真正抛出您的异常,因为将首先抛出除以零。ArithmeticException是一个RuntimeException,因此不是一个检查异常,它不需要或保证任何声明。我已经删除了它,所以你的异常被抛出:

class CustomException extends Exception{
  CustomException(){
    super();
  }
  CustomException(String message){
    super(message);
  }
}
Run Code Online (Sandbox Code Playgroud)

为什么你的原因Second的方法调用‘不会让我过去’,是因为你把一个Exceptionmethod1你所调用你Second的方法调用。所以你需要将你的调用包装method1()在一个 try-catch 块中,或者throws它。由于您“想要从第三个捕获它”,因此您需要throws在方法的声明中使用它:

class First {
  protected void method1() throws CustomException {
  // will cause "java.lang.ArithmeticException: / by zero" not CustomException
  //  int number=10/0;
  //  System.out.println("method 1" + number);
    throw new CustomException("Divided by zero");
  }
} // missing end brace
Run Code Online (Sandbox Code Playgroud)

除了添加的大括号外,这是不变的:

class Second extends First {
  // error: unreported exception CustomException; must be caught or declared to be thrown
  // protected void method2() {  // your version

  protected void method2() throws CustomException {
    method1();
  }
} // missing end brace
Run Code Online (Sandbox Code Playgroud)