在Java异常处理中,开发者常因对机制理解不深而陷入一些误区。以下是最常见的误区及正确实践,结合代码示例说明:
try {
int a = 1 / 0;
} catch (Exception e) {
// 什么都不做
}
catch (Exception e) {
log.error("计算失败", e);
throw e; // 或包装后抛出
}
Throwable / Exception 过于宽泛try {
doSomething();
} catch (Exception e) {
// 捕获所有异常
}
NullPointerException、RuntimeExceptioncatch (IOException e) {
// 只处理可预期的异常
}
try {
int num = Integer.parseInt(str);
} catch (NumberFormatException e) {
num = 0;
}
if (str != null && str.matches("\\d+")) {
num = Integer.parseInt(str);
} else {
num = 0;
}
finally 中返回或抛异常try {
return 1;
} finally {
return 2; // 覆盖 try 的返回值
}
finally 中的 return 会覆盖 try / catch 的返回值int result;
try {
result = 1;
} finally {
// 只做资源释放
}
return result;
finally 中关闭资源但忽略异常finally {
fos.close(); // 可能抛 IOException
}
try (FileOutputStream fos = new FileOutputStream("a.txt")) {
fos.write(1);
}
RuntimeException 却不保留原因catch (IOException e) {
throw new RuntimeException("error");
}
throw new RuntimeException("IO error", e);
catch (Exception e) {
log.error("error", e);
}
catch (Exception e) {
log.error("error", e);
throw e;
}
public User(String name) {
if (name == null) {
throw new IllegalArgumentException();
}
}
throw new IllegalArgumentException("name must not be null");
catch 能捕获子线程异常try {
new Thread(() -> {
throw new RuntimeException();
}).start();
} catch (Exception e) {
// 捕获不到
}
Thread t = new Thread(() -> {
throw new RuntimeException();
});
t.setUncaughtExceptionHandler((t1, e) -> log.error("error", e));
t.start();
class MyException extends Exception {}
class MyException2 extends Exception {}
IllegalArgumentException、IllegalStateException)| 误区 | 核心问题 |
|---|---|
| 吞异常 | 信息丢失 |
| 捕获太宽 | 掩盖错误 |
| 用异常控制流程 | 性能 + 可读性差 |
| finally return | 覆盖结果 |
| 不保留 cause | 排查困难 |
| 只 log 不抛 | 状态不一致 |
| 线程异常 | 捕获不到 |
| 滥用自定义异常 | 设计复杂 |
如果你愿意,我也可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。