最常见的运行时异常有5个:nullpointerexception、arrayindexoutofboundsexception、arithmeticexception、classcastexception、numberformatexception,均源于逻辑疏漏;它们不强制捕获,因属程序缺陷而非外部不可控因素,编译器放行旨在倒逼源头修复而非掩盖问题。

最常见的运行时异常就5个,90%的线上 NullPointerException、ArrayIndexOutOfBoundsException、ArithmeticException、ClassCastException、NumberFormatException 都源于这五类逻辑疏漏。
为什么这些异常不强制捕获?
因为它们本质是程序逻辑缺陷,不是外部不可控因素——编译器放行,是倒逼你从源头修复,而不是用 try-catch 掩盖问题。
-
NullPointerException:调用null对象的方法或访问其字段(如str.length()但str == null) -
ArrayIndexOutOfBoundsException:数组下标或 <code>>= array.length(注意:list.get(i)同样抛此异常) -
ArithmeticException:仅在整数除零时触发(10 / 0),浮点数除零返回Infinity不抛异常 -
ClassCastException:强制转型失败((String) new Date()),用instanceof预检可避免 -
NumberFormatException:字符串转数字格式非法(Integer.parseInt("abc")),推荐先用StringUtils.isNumeric()或正则校验
别把 RuntimeException 当“可以不管”的借口
它们不会中断编译,但会在运行时炸掉线程——尤其在异步任务、定时调度、RPC响应中静默失败,日志里只留一行堆栈,排查成本远高于预防。
- 空指针最常发生在未判空的链式调用:
user.getAddress().getCity()→ 改成Optional.ofNullable(user).map(User::getAddress).map(Address::getCity).orElse(null) - 数组/集合越界多因硬编码下标或循环条件写错:
for (int i = 0; i → 少一个等号就是越界 - 类型转换异常高频于 JSON 反序列化后直接强转,应优先用泛型解析(如
gson.fromJson(json, new TypeToken<list>>(){}.getType())</list>)
自定义运行时异常怎么用才不翻车?
继承 RuntimeException 是对的,但别滥用——它绕过编译检查,意味着调用方根本不知道会抛什么,容易导致防御性编程缺失。
立即学习“Java免费学习笔记(深入)”;
- 命名要带业务语义:
InsufficientBalanceException比BusinessException更易理解 - 构造函数必须传
message和cause(原始异常),否则上游无法做分类重试或告警 - 禁止在
catch块里吞掉原始异常再抛自定义异常却不设cause,等于丢掉关键上下文
真正难处理的从来不是异常类型本身,而是当 NullPointerException 出现在第17层调用栈深处,而你的日志里只有 at com.xxx.service.UserServiceImpl.getUser(UserServiceImpl.java:234) ——此时有没有在关键入参打点、是否启用 -XX:+ShowCodeDetailsInExceptionMessages(JDK14+),比记住多少异常名都重要。










