防范npe和arithmeticexception需从编码源头设防:字符串比较用常量.equals(变量),包装类型拆箱前判空,集合返回空集合而非null,除法前校验分母,bigdecimal除法指定精度与舍入模式。

防范 NullPointerException(NPE)和 ArithmeticException,关键不是等它发生再捕获,而是从写代码的第一行就切断触发路径。这两类异常几乎都源于可预见的疏漏——比如没校验 null、没检查除零、或对包装类型盲目拆箱。提前在变量使用、方法设计、数据校验三个环节设防,就能大幅降低崩溃概率。
字符串与对象比较:别让null参与调用
常见错误是用可能为 null 的变量调用方法,例如 s.equals("abc")。一旦 s 为 null,立刻抛 NPE。正确做法是把常量放前面:"abc".equals(s),因为字符串字面量绝不会是 null。
- 所有涉及
equals()、hashCode()、toString()的调用,优先让已知非空对象作为主调方 - 自定义类重写
equals()时,开头加if (obj == null) return false;和if (getClass() != obj.getClass()) return false; - 用
Objects.equals(a, b)替代手动判空比较,它内部已处理两边 null 的情况
包装类型与自动拆箱:警惕“静默爆炸”
Integer、Long、Boolean 等包装类型赋值为 null 后直接赋给基本类型,会触发自动拆箱并立即抛 NPE,且无明显提示:
Integer code = null;<br>int status = code; // 这里崩了
- 接收外部参数(如 Controller 入参、DAO 查询结果)时,不假设包装类型一定有值
- 需要基本类型值时,显式判空或用
Integer.intValue()前加if (code != null) - 更安全的方式是用
code != null ? code : 0或Optional.ofNullable(code).orElse(0)
集合与链式调用:拒绝返回 null,拥抱 Optional
方法返回 null 是 NPE 的温床。比如 queryOrders(userId) 返回 null,调用方遍历时直接崩溃;又如 user.getAddress().getCity().getName(),任一环节为 null 就中断。
- 集合类方法一律返回空集合,而不是 null:
return orders != null ? orders : Collections.emptyList(); - 对可能缺失的对象链,改用
Optional安全提取:Optional.ofNullable(user)<br> .map(User::getAddress)<br> .map(Address::getCity)<br> .map(City::getName)<br> .orElse("未知") - 公共 API 方法的参数和返回值,配合
@NonNull/@Nullable注解(如 Lombok 或 JetBrains),让 IDE 提前标出风险点
算术运算:盯紧除零、取模与 BigDecimal
ArithmeticException 主要发生在整数除法分母为 0,或 BigDecimal 除不尽又没指定舍入规则时。浮点数除零不会抛此异常(得 Infinity),所以重点在 int、long 类型的 / 和 %。
- 所有除法前强制校验分母:
if (divisor != 0) { result = dividend / divisor; },尤其参数来自表单、配置或数据库 - 用
BigDecimal做金额/精度敏感计算时,禁止裸调divide();必须指定精度和舍入模式:bigA.divide(bigB, 2, RoundingMode.HALF_UP) - 负数取模需注意:Java 中
-5 % 2 == -1。若业务要求余数 ≥ 0,统一用((a % b) + b) % b归正











