java短路规则本质是“结果确定就停”,&&左假则右不执行,||左真则右不执行,核心用于防npe、除零等异常;&和|无短路,两边必执行。

Java 中的短路规则本质是“结果确定就停”,不是所有条件都必须执行。它不只影响性能,更是防止 NullPointerException 和 ArithmeticException(如除零)的关键防线。核心在于:&& 和 || 会根据左操作数的值决定是否跳过右操作数;而 & 和 | 总是两边都算,容易出错。
短路与(&&):左边为 false 就不看右边
这是防空指针最常用的方式。只要左边判断能提前否定整个表达式,右边危险操作就不会触发。
- ✅ 安全写法:
if (obj != null && obj.getName().length() > 0)—— obj 为 null 时,obj.getName()根本不执行 - ❌ 危险写法:
if (obj != null & obj.getName().length() > 0)—— 即使 obj 是 null,& 还是会强行调用getName(),抛出NullPointerException - 数组判空也同理:
if (arr != null && arr.length > 0 && arr[0] == 1),层层递进,每一步都依赖前一步的安全前提
短路或(||):左边为 true 就不看右边
它常用于兜底、默认值或规避非法运算,比如避免除零。
- ✅ 防除零:
if (divisor == 0 || value / divisor > 10)—— divisor 为 0 时,右边的除法不会执行 - ❌ 错误顺序:
if (value / divisor > 10 || divisor == 0)—— 先算除法,divisor 为 0 就直接报ArithmeticException - 也可用于提供默认行为:
String name = user != null ? user.getName() : "guest"等价于更安全的String name = (user != null && user.getName() != null) ? user.getName() : "guest"
非短路运算符(& 和 |)什么时候能用?
它们不是“错误”,只是用途不同:主要用在位运算,或你明确需要两边都执行的极少数场景。
- 位运算:
int flags = OPTION_A & OPTION_B,这里 & 是按位与,不是逻辑判断 - 调试计数(慎用):
if ((a > 5) & (b++ > 0))——想确保 b 总是自增,但业务逻辑中几乎不该依赖这种副作用 - 一般建议:布尔上下文中,优先选 && 和 ||;除非你清楚知道为什么必须两边都执行
实际避坑要点
短路本身不难,但容易忽略细节:
-
顺序很重要:把轻量、高概率失败的检查放左边(如
obj != null、list != null、count > 0),把耗时或有风险的操作放右边 - 别依赖右操作数的副作用:日志、计数、状态变更如果写在 && 或 || 的右边,可能被跳过,导致逻辑不一致
-
链式调用要逐层短路:比如
user != null && user.getProfile() != null && user.getProfile().getAvatar() != null,缺一不可 -
字符串比较防 NPE 更简单的方法:
"admin".equals(obj.getRole())比obj.getRole() != null && "admin".equals(obj.getRole())更简洁,因为已知字面量非 null
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











