核心区别在于:&是“全量执行”,&&是“能省则省”——&无条件执行左右两边,&&在左操作数为false时跳过右操作数,影响副作用触发、数据类型支持(&可位运算,&&仅限布尔)及性能表现。

核心区别在于:& 是“全量执行”,&& 是“能省则省”——这直接决定性能开销和逻辑安全性。
执行时机不同,影响副作用是否触发
当表达式中含方法调用、自增/自减、对象访问等有副作用的操作时,两者行为明显分化:
- & 会无条件执行左右两边,哪怕左边已为 false;
- && 一旦左边为 false,右边完全跳过不执行。
例如:
if (obj != null & obj.isValid()) → 即使 obj 为 null,仍会调用 obj.isValid(),抛出 NullPointerException;
if (obj != null && obj.isValid()) → obj 为 null 时,isValid() 根本不调用,安全通过。
数据类型约束不同,用途天然分离
& 是多面手,&& 是专精者:
- & 可用于整数(按位与)或布尔(非短路逻辑与),编译器根据操作数类型自动切换语义;
- && 只接受布尔表达式,语法上禁止用于 int 等数值类型,否则编译报错。
比如:
int a = 5 & 3; ✅ 合法,结果是 1(二进制 101 & 011);
int b = 5 && 3; ❌ 编译失败:“bad operand types for operator &&”。
性能差异取决于右侧代价,但多数场景 && 更优
所谓“细微差别”,其实很实在:
- 若右侧是简单布尔变量(如 flag),性能差异可忽略;
- 若右侧是数据库查询、IO 操作、复杂计算或可能抛异常的方法,则 & 会白白浪费资源甚至引发错误;
- 在循环高频判断、高并发校验等场景中,&& 的短路机制能显著降低平均开销。
什么时候必须用 &?
两种典型情况:
- 需要确保右侧一定执行:比如同时记录日志和更新状态,两个动作都不可省略;
- 进行位运算:判断奇偶((n & 1) == 0)、掩码提取、权限位操作等,此时 & 不是逻辑运算,而是底层位处理。










