在Java中,异常分为检查异常(checked)和未检查异常(unchecked)。
Exception,但不继承自RuntimeException。编译器要求显式处理这些异常,使用try-catch或者在throws中声明。RuntimeException。编译器不要求强制处理这些异常。public void readFile(String file) throws IOException { /* ... */ } // checked public void divide(int a, int b) { int res = a/b; } // unchecked (ArithmeticException)
主要的区别是——检查异常用于可预期的、可恢复的情况(例如,输入输出错误),而未检查异常用于程序逻辑错误或无法恢复的严重情况(例如,NullPointerException)。
问题: 如果您的方法可能抛出未检查异常,是否需要处理或在throws中声明?
答案: 不需要。编译器不要求检查或声明不可恢复(unchecked)异常。这些异常的处理由您自行决定;可以使用try-catch,但通常情况是让其“崩溃”,一直到全局处理程序。
public void foo() { throw new IllegalArgumentException(); } // 不需要处理或声明
故事
在一个银行API项目中,在处理输入输出错误时抛出了
RuntimeException而不是检查异常。因此,客户没有被迫处理这些异常,导致在失去与服务器的连接时程序错误,应用程序“崩溃”而未告知用户。
故事
开发人员在方法签名中声明了多余的
throws Exception(例如,数据库),导致所有使用的方法都被迫使用try-catch或也需throws。这使代码变得混乱,降低了可读性,并且使重构变得困难。
故事
在其中一个微服务中,捕获了所有异常,使用了通用
catch (Exception e)。这也捕获了未检查异常(例如,NullPointerException),导致严重错误被“安静地”忽略——服务处理了不正确的数据。