短路求值是Java中防止空指针异常最轻量的手段,依赖&&和||的天然短路逻辑,仅当判空与取值在同一布尔表达式内才生效,脱离表达式或使用&则失效。

短路求值是 Java 流程控制中防止空指针异常(NPE)最轻量、最直接的手段之一。它不依赖额外工具或框架,靠的是 && 和 || 运算符天然的执行逻辑:一旦左侧已能确定整个表达式结果,右侧就完全不执行——危险调用自然被跳过。
把判空和取值锁在同一个表达式里
这是生效的前提。短路保护只存在于单个布尔表达式内部,脱离上下文就失效。
- ✅ 安全写法:if (user != null && user.getProfile() != null && user.getProfile().isVerified()) —— 每一步都是前一步成立的条件,任一为 false,后续方法都不会触发
- ❌ 危险写法:if (user != null) { String level = user.getLevel(); } —— 即使判了空,
user.getLevel()单独成行,就失去短路保护;若该方法返回 null,后面用level.length()还是会 NPE - ⚠️ 注意:
&不是&&,前者不短路。写成user != null & user.getProfile() != null时,哪怕 user 是 null,getProfile()仍会被调用,立刻抛异常
多层嵌套访问的安全链式写法
访问深层属性(如 order.getItems().get(0).getProduct().getName())时,不能只判第一层,必须逐级“守门”。
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- ✅ 推荐:if (order != null && order.getItems() != null && !order.getItems().isEmpty() && order.getItems().get(0) != null && order.getItems().get(0).getProduct() != null)
- ? 小技巧:用
!list.isEmpty()替代list.size() > 0,避免 list 为 null 时调用size()报错 - ? 可进一步封装为布尔方法:
isFirstItemValid(order),既复用逻辑,又保持短路语义
用 || 做兜底或防除零等副作用操作
|| 的短路特性同样能防 NPE,尤其适合提供默认值或跳过非法运算。
立即学习“Java免费学习笔记(深入)”;
- ✅ 防除零:if (divisor == 0 || value / divisor > 10) —— divisor 为 0 时,除法根本不会执行
- ✅ 设默认值:String name = (user != null && user.getName() != null) ? user.getName() : "guest"
- ❌ 错序危险:if (value / divisor > 10 || divisor == 0) —— 除法先算,必然崩溃
短路不保护赋值语句,只保护表达式求值
这是最容易忽略的关键点:短路机制只影响布尔表达式中右侧子表达式的是否执行,对变量赋值本身没有约束力。
- ✅ 安全:String city = user != null && user.getAddress() != null ? user.getAddress().getCity() : null;
- ❌ 危险:String city = user.getAddress().getCity(); —— 即使前面刚写过
if (user != null),这行单独赋值仍可能 NPE - ? 记住:保护是否发生,取决于“是否在同一表达式中完成判空 + 取值”,而不是“之前有没有判过空”

















