catch(Exception e)抓不到OutOfMemoryError,因为Exception与Error是Throwable的两个平级子类,无继承关系;OutOfMemoryError直接继承Error,不在Exception继承链上。
catch(Exception e) 为什么抓不到 OutOfMemoryError
因为 Exception 和 Error 是 Throwable 的两个**平级子类**,没有继承关系。你写 catch (Exception e),就像想用渔网捞飞机——类型根本不匹配。
-
OutOfMemoryError、StackOverflowError都直接继承自Error,不在Exception的继承链上 - 编译器允许你写
catch (Error e),但这是危险操作:此时 JVM 很可能已处于不可靠状态(比如堆内存全满、栈帧损坏) - 真正该做的是在 JVM 启动参数里加
-XX:+HeapDumpOnOutOfMemoryError,配合jstat或VisualVM定位泄漏点,而不是靠 try-catch“兜底”
什么时候必须处理,什么时候可以不写 try-catch
Java 编译器只强制你管一类异常:Checked Exception——即直接继承 Exception 但**不继承 RuntimeException 的那些,比如 IOException、SQLException。
- 不处理?编译直接报错:
Unhandled exception type IOException -
RuntimeException及其子类(如NullPointerException、ArrayIndexOutOfBoundsException)属于Unchecked Exception,编译器放行,但建议用判空、校验、防御性编程提前规避 -
Error全系都是 unchecked,编译器完全不管——但这不等于“可以放心 catch”,而是“你不该去 catch”
自定义异常该继承 Exception 还是 Error
永远选 Exception 或它的子类(比如业务异常继承 RuntimeException),**绝不能继承 Error**。