转载

Java如何在没有throws签名的函数中手动抛出异常

如果想在方法中抛出异常,像下面这样直接 throw 是不行的。

public void test() {
    throw new Exception();
}

这时编译器会给我们一个错误:

Error:(101, 13) java: 未报告的异常错误java.lang.Exception; 必须对其进行捕获或声明以便抛出

想要在方法中手动抛出异常,Java编译器给我们提供了两种选择,要么在方法签名中添加 throws 声明:

public void test() throws Exception {  
    throw new Exception();  
}

要么用 try-catch 封印:

public void test() {  
    try {  
        throw new Exception();  
    } catch (Exception e) {  
        e.printStackTrace();  
    }  
 }

对于第二种方法,除了语法正确外,屁用没有。

在一般情况下,或则只是为了解决未捕获异常错误,第一种方法已经足够。但是偏偏就有这么一种情况。当我们重写一个方法时,想在方法中抛出异常,但是方法签名中又没有 throws 声明。这就要了老命了,简直让人抓狂,大骂傻逼抓娃。

遇到这种情况也不是毫无办法,考虑下面的函数:

public static double sang(double a, double b) {  
    return a / b  
}  
​  
public static void main(String/[/] args) {  
    sang(1, 0);  
}

用1和0去调用上面的 sang 函数,铁定是要抛出异常的。奇怪的是它的方法签名中既没有 throws 声明,也没有 try-catch 封印,冥冥之中似乎透着那么丁点儿希望。

说到这里,如果你对Java异常分类有所了解的话,已经能从中窥探一二了。Java异常全部继承自 Throwable ,又分为 ErrorExceptionError 是运行时系统内部错误,编写应用程序很少涉及。 Exception 又有两个分支,分别是 RuntimeExceptionCheckedException ,这就是我们常听说的运行时异常和检测异常,而Java编译器强制必须捕获的就是检查异常。

我们在 test 函数中无法直接抛出异常正是因为被抛出的是一个检查异常,而 double 函数抛出的是运行时异常。所以解决方案也就呼之欲出了,只要将异常包装成运行时异常,就能骗过编译器,成功抛出异常了。

public void test() {  
    throw (RuntimeException)new Exception();  
}

当然,这里还要求调用 test 的函数能够捕获到运行时异常,否则抛出这个异常也就没有意义了。如果你是自己写函数调用 test ,那当然皆大欢喜,如果第三方代码库,那就只能祝好运了。

原文  https://segmentfault.com/a/1190000021513548
正文到此结束
Loading...