Java中避免空指针异常的关键是利用&&和||的短路特性,将判空与取值/调用置于同一表达式;需逐级检查链式调用、集合判空+非空校验,并合理使用Optional。

Java 中用逻辑运算符避免空指针异常,关键在于掌握 && 和 || 的短路特性,并把“判空”和“取值/调用”锁在同一个表达式里。不是光写个 if (obj != null) 就安全了——如果后面再单独调用 obj.method(),照样崩。
用 && 把判空和方法调用绑在一起
这是最常用也最有效的防护方式。&& 左边为 false 时,右边根本不会执行,天然阻断后续危险操作。
- ✅ 安全写法:if (user != null && user.getName() != null && user.getName().length() > 0) —— 只要 user 是 null,getName() 根本不触发
- ❌ 危险写法:if (user != null) { String name = user.getName(); ... } —— user.getName() 返回 null 后,name.length() 还是可能 NPE
- ⚠️ 注意:不能用 & 替代 &&,& 是位运算符,不短路,user 为 null 时 user.isActive() 仍会执行,直接抛异常
多层嵌套访问必须逐级守门
访问 user.getProfile().getAvatar().getUrl() 这类链式结构,不能只检查 user 是否为空。每一环节都可能是 null,必须每一步都作为前置条件参与判断。
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
- ✅ 正确:user != null && user.getProfile() != null && user.getProfile().getAvatar() != null && user.getProfile().getAvatar().getUrl() != null
- ? 小技巧:把这类检查封装成布尔方法,比如 hasValidUrl(user),主流程更干净,复用性也更强
- ⚠️ 别在三元运算符外单独写危险调用,例如 String url = user.getProfile().getAvatar().getUrl(); 即使前面用了 ? :,这行代码本身已脱离保护范围
集合操作必须一次判空+判空内容
对 List、Map、Set 等集合,既要防 null,也要防空集合引发的 get(0) 或 keySet() 调用失败。
立即学习“Java免费学习笔记(深入)”;
- ✅ 推荐:if (list != null && !list.isEmpty()) { process(list.get(0)); } —— list 为 null 时,!list.isEmpty() 不执行
- ? 更优实践:方法返回集合时,优先返回 Collections.emptyList() 而非 null;入参集合用 Objects.requireNonNull() 在开头校验
- ⚠️ 避免分步写:if (list != null) { if (!list.isEmpty()) { ... } } —— 看似安全,但后续若漏掉判空直接 list.forEach(),风险仍在
用 Optional 替代裸 null(Java 8+)
Optional 不是万能解药,但它是语义更清晰、强制处理缺失值的现代方案。
- ✅ 查找并安全取值:userService.findUserById(1001).map(User::getEmail).orElse("no@email.com")
- ✅ 避免层层判空:Optional.ofNullable(user).map(u -> u.getProfile()).map(p -> p.getAvatar()).isPresent()
- ⚠️ 注意:Optional 本身不能为 null,但不要滥用,比如包装局部变量或返回 new Optional(),反而增加复杂度

















