
Java里 && 和 & 看似都能“判断真假”,但行为完全不同
直接说结论:&& 是逻辑与,支持短路;& 是按位与,在布尔上下文中也做逻辑运算,但**不短路**。这意味着:如果左边表达式为 false,&& 根本不会执行右边;而 & 一定两边都算——哪怕右边是 method() 这种有副作用的调用。
什么时候用 &&?绝大多数布尔判断场景都该用它
日常写 if、while 条件时,只要目的是“逻辑判断”,就该无条件选 &&:
-
null安全检查:if (obj != null && obj.isValid())—— 如果obj是null,obj.isValid()根本不执行,避免NullPointerException - 资源状态校验:
if (file.exists() && file.canRead())—— 不会因exists()返回false还去调用canRead() - 性能敏感路径:
&&跳过右侧计算,尤其当右侧是耗时方法或复杂表达式时
为什么有人误用 &?常见错误现象和陷阱
典型症状是:代码在某些输入下抛异常,换个顺序又不抛了;或者日志里发现“不该执行的方法”被执行了两次。
- 把
&当成更“严格”的&&—— 实际上它只是“不跳过”,跟“严格”无关 - 复制粘贴时漏掉一个
&,比如把&&写成&,IDE 往往不报错(因为布尔值也能参与按位运算) - 在需要副作用的极少数场景硬用
&(例如必须确保两个方法都执行),但没加注释说明意图,后续维护者容易改成&&导致逻辑断裂 -
&对boolean是逻辑运算,但对整数才是真·按位运算;混用类型时(比如int & boolean)会编译失败,别指望它自动转换
& 的合法用途其实很窄,别强行找理由用它
真正该用 & 的地方只有两类:
立即学习“Java免费学习笔记(深入)”;
- 对整数做位操作:
flags & 0x01、value & ~MASK - 明确要求两侧表达式**必须都执行**的布尔场景(极少):
if (logRequest() & validateInput())—— 这里logRequest()的副作用不能被跳过 - 注意:这种写法可读性差,更推荐拆成两行 + 显式
if,除非在性能关键且已充分压测的底层代码中
混淆点在于:Java 允许 boolean & boolean 编译通过,但这不是设计来替代 && 的,而是为了运算符一致性。实际工程中,99% 的布尔连接都应该用 &&。










