这是一个非常经典且重要的问题。简短的回答是:不一定必须处理,但你必须“有所表示”。
在 Java 中,受检异常(Checked Exception,通常是 Exception 类及其子类,但不包括 RuntimeException 及其子类)之所以被设计出来,是因为编译器强制要求程序员意识到这些可能发生的错误。
你有以下几种“处理”方式,但绝对不能无视它:
这是最标准的处理方式。当你认为在这个方法内部有能力解决这个异常时,使用这种方式。
try {
FileInputStream fis = new FileInputStream("file.txt");
} catch (FileNotFoundException e) {
// 处理异常:比如打印日志、给默认值、或者提示用户文件不存在
System.out.println("文件未找到,使用默认配置。");
}
如果你认为当前方法处理不了这个异常,或者你希望调用你的方法的上层代码来处理它,你可以选择声明抛出。
throw 关键字。throws 关键字。// 方法签名上声明 throws,把锅丢给调用者
public void readFile() throws FileNotFoundException {
FileInputStream fis = new FileInputStream("file.txt");
// 这里没有 try-catch,编译器会要求你加上 throws 声明
}
注意:如果你声明了抛出,那么调用 readFile() 方法的地方,又必须面临同样的“二选一”局面(要么 try-catch,要么继续 throws)。
如果你既不捕获,也不声明抛出,代码将无法通过编译。
❌ 错误示例:
public void readFile() {
// 编译错误!FileNotFoundException 是受检异常
FileInputStream fis = new FileInputStream("file.txt");
}
有些程序员为了省事,会写出这样的代码:
try {
// do something
} catch (Exception e) {
// 空 catch 块,或者仅仅 e.printStackTrace()
}
或者:
public void method() throws Exception {
// 直接抛出 Exception,掩盖了具体异常
}
评价:这是非常糟糕的编程习惯。空 catch 块相当于“吞掉”了异常,会导致程序在出错时悄无声息,极难调试。
| 场景 | 建议做法 |
|---|---|
| 你能修复这个问题 | 捕获并处理(例如:文件不存在就创建,网络断了就重试)。 |
| 你无法处理,需要上层决定 | 声明抛出(例如:底层读取文件失败,告诉业务层“读取失败”)。 |
| 这是一个逻辑错误 | 重新思考:也许它不应该是一个受检异常。如果是代码逻辑错误(如空指针、除零),通常应该抛出 RuntimeException(非受检异常)。 |
核心逻辑:受检异常的存在是为了提醒你“这里可能会出错,请做好预案”。你必须通过代码告诉编译器你的预案是什么(要么我处理了,要么我告诉调用者我有可能会出这个错)。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。