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

huangapple go评论83阅读模式
英文:

How to leave the error catching to the subclass?

问题

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() {
        try {
            method1();
        } catch (CustomException ex) {
            throw new RuntimeException(ex); // Rethrow as an unchecked exception
        }
    }
}

public class Third extends Second {
    protected void method3() {
        try {
            method2();
        } catch (RuntimeException ex) {
            if (ex.getCause() instanceof CustomException) {
                CustomException customEx = (CustomException) ex.getCause();
                System.out.println("Caught the exception");
                System.out.println(customEx.getMessage());
            } else {
                throw ex; // Rethrow if it's not the expected exception
            }
        }
    }
}
英文:
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());
        } 
}

In this code first throws an exception and I want to catch it from third (second will not handle error). But second's method call won't let me pass. How can I fix this?

答案1

得分: 9

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

这个例子基于你的代码:

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

并且它会输出:

捕获了异常
被零除

<br/>

添加了CustomException的缺失实现:

class CustomException extends Exception{
  CustomException(){
    super();
  }
  CustomException(String message){
    super(message);
  }
}

<br/>

请注意,你的代码实际上永远不会真正抛出你的异常,因为首先会抛出零除。ArithmeticException是一个RuntimeException,因此不是已检查的异常,不需要或不值得任何声明。我已经移除了它,这样你的异常就会被抛出:

class First {
  protected void method1() throws CustomException {
  // 会导致&quot;java.lang.ArithmeticException: / by zero&quot; 而不是 CustomException
  //  int number=10/0;
  //  System.out.println(&quot;method 1&quot; + number);
    throw new CustomException(&quot;被零除&quot;);
  }
} // 缺失结束大括号

<br/>

你的Second的方法调用"won't let me pass"的原因是因为你在method1中抛出了一个Exception,而你在Second的方法调用中调用了它。所以你需要将对method1()的调用包装在try-catch块中,或者在方法的声明中使用throws。由于你"想从third中捕捉到它",你需要在方法的声明中使用throws

class Second extends First {
  // 错误:未报告的异常 CustomException;必须捕获或声明为抛出
  // protected void method2() {  // 你的版本

  protected void method2() throws CustomException {
    method1();
  }
} // 缺失结束大括号

<br/>

这段代码没有改变,除了添加了缺失的大括号:

class Third extends Second {
  protected void method3(){
    try {
      method2();
    } catch (CustomException ex) {
      System.out.println(&quot;捕获了异常&quot;);
      System.out.println(ex.getMessage());
    } 
  } 
} // 缺失结束大括号
英文:

For checked exceptions (not any RuntimeException), they must be either handled or thrown by the method that calls another method that throws the exception. This is also explained in more depth in the tutorial by Oracle on Exceptions.

This example is based on your code:

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

and it will print:

Caught the exception
Divided by zero

<br/>

Added the missing implementation of CustomException:

class CustomException extends Exception{
  CustomException(){
    super();
  }
  CustomException(String message){
    super(message);
  }
}

<br/>

Note that your code would never get to actually throwing your exception, as division by zero would be thrown first. ArithmeticException is a RuntimeException and therefore not a checked exception, and it doesn't need or warrant any declaration. I've removed it so your exception is thrown:

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

<br/>

The reason why your Second's method call "won't let me pass" is because you're throwing an Exception in method1 which you are calling in your Second's method call. So you need to either wrap your call to method1() in a try-catch block, or throws it. Since you "want to catch it from third", you need to throws it in the declaration of the method:

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

<br/>

This is unchanged, except for the added brace:

class Third extends Second {
  protected void method3(){
    try {
      method2();
    } catch (CustomException ex) {
      System.out.println(&quot;Caught the exception&quot;);
      System.out.println(ex.getMessage());
    } 
  } 
} // missing end brace

huangapple
  • 本文由 发表于 2020年8月18日 19:38:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/63467821.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定