应捕获Exception而非Error;Checked Exception需强制处理,Unchecked Exception应预防而非捕获;自定义异常必须继承Exception而非Error。

Exception 是程序能干预的意外,Error 是 JVM 已失控的信号
直接说结论:你该捕获 Exception,但几乎不该捕获 Error。这不是“要不要写 try-catch”的风格问题,而是语义层面的分水岭——Exception 意味着“这事还能救”,Error 意味着“地基塌了,别修房间了”。
为什么 catch(Error e) 是危险操作?
捕获 Error 不仅徒劳,还可能掩盖真正的问题,让系统在不可靠状态下继续运行,引发更隐蔽的崩溃或数据错乱。
-
OutOfMemoryError发生时,JVM 可能已无法分配新对象,此时即使你catch住,连日志都可能因内存不足而写失败 -
StackOverflowError出现,说明调用栈已满,再进一层catch块本身就会再次触发该错误 -
NoClassDefFoundError往往是类路径污染或版本冲突导致,捕获后重试加载基本无效 - 极少数合理场景(如主入口统一兜底)只做三件事:记录堆栈、发告警、调用
System.exit(1)——不是恢复,是优雅终止
Exception 分两类,处理策略完全不同
编译器强制你面对的,和它放任不管的,背后是设计哲学差异:前者是“外部世界可能出问题”,后者是“你代码写得不够严谨”。
-
检查型异常(Checked Exception):
IOException、SQLException等。不try-catch或不throws,编译直接报错。它们代表可控外部依赖的失败,比如文件被删、网络断开。你应该:提供默认值、降级逻辑、重试机制,或向上声明让调用方决策 -
非检查型异常(Unchecked Exception):
NullPointerException、IllegalArgumentException等(即RuntimeException子类)。编译器不管,但你应该在源头预防:参数判空、集合判 size、数值做范围校验。而不是靠层层catch补漏
自定义异常时,永远别继承 Error
这是新手容易踩的硬性红线。自定义类型必须明确表达“这是程序可理解、可响应的异常事件”,而 Error 的语义是“JVM 自己都扛不住了”。继承错类,会导致异常被误判为不可恢复,破坏整个异常处理链路。
立即学习“Java免费学习笔记(深入)”;
public class UserNotFoundException extends Exception { // ✅ 合理:业务可感知、可提示、可重定向
public UserNotFoundException(String message) {
super(message);
}
}
public class InvalidConfigError extends Error { // ❌ 危险:误导调用方以为这是系统级致命故障
public InvalidConfigError(String message) {
super(message);
}
}
真正容易被忽略的是:很多团队把“配置错误”“参数非法”也命名为 xxxError,这会污染异常语义,让监控系统误判严重等级。命名即契约——叫 Exception 就意味着它该被处理,而不是被忽略。










