自定义Add异常编译报错:未报告的异常Add需捕获或声明抛出
首先,咱们来拆解一下你遇到的编译错误:
Practice.java:8: error: unreported exception Add; must be caught or declared to be thrown
throw new Add("Addition has been performed");
这个错误的核心原因是:你的Add类继承了Throwable,而Throwable的子类(除了RuntimeException及其子类)属于受检异常(Checked Exception)。Java规定,受检异常必须被显式处理——要么用try-catch块捕获,要么在方法签名里用throws声明抛出。你的main方法直接抛出了Add异常,但既没捕获也没声明,所以编译器报错了。
接下来给你两种可行的修复方案:
方案一:把自定义异常改成非受检异常(推荐)
如果你的这个异常不需要强制调用者处理,可以让Add继承RuntimeException(它是Throwable的间接子类,属于非受检异常),这样编译器就不会要求你必须处理它了。修改后的代码如下:
class Test { public static void main(String[] args) { int a = 9, b = 67, result; result = a + b; throw new Add("Addition has been performed"); } } class Add extends RuntimeException { Add() { super(); printStackTrace(); } Add(String message) { super(message); System.out.println(message); printStackTrace(); } }
注意:其实你在构造函数里手动调用printStackTrace()不是必须的——当异常被抛出时,JVM会自动打印堆栈跟踪信息。不过如果你想在构造时额外输出内容,这么写也没问题。
方案二:显式处理受检异常
如果你坚持让Add继承Throwable,那必须在main方法上声明抛出该异常,或者用try-catch捕获它:
子方案2.1:在方法签名声明throws
class Test { // 在main方法上声明抛出Add异常 public static void main(String[] args) throws Add { int a = 9, b = 67, result; result = a + b; throw new Add("Addition has been performed"); } } class Add extends Throwable { Add() { printStackTrace(); } Add(String message) { System.out.println(message); printStackTrace(); } }
子方案2.2:用try-catch捕获异常
class Test { public static void main(String[] args) { int a = 9, b = 67, result; result = a + b; try { throw new Add("Addition has been performed"); } catch (Add e) { // 这里可以添加异常处理逻辑,比如打印信息或者做恢复操作 System.out.println("Caught the custom Add exception"); } } } class Add extends Throwable { Add() { printStackTrace(); } Add(String message) { System.out.println(message); printStackTrace(); } }
最后提醒一下:通常自定义异常时,除非有特殊需求,否则优先继承Exception(受检)或RuntimeException(非受检),而不是直接继承Throwable——因为Throwable还包含了Error类(比如虚拟机错误),直接继承它会混淆异常和错误的边界。
内容的提问来源于stack exchange,提问作者Dr. Sikandar

