java中&和&&不可混用:&是位运算符,不短路;&&是逻辑运算符,支持短路。权限掩码用&、|、~,异或^用于交换变量或翻转标志,移位需注意符号与溢出。

Java位运算符的常见误用:&和&&混用导致逻辑错误
很多人在条件判断里写 & 代替 &&,结果发现代码没报错但行为诡异——比如右边表达式被意外执行,或者空指针没被短路。这是因为 & 是位运算符,对布尔值做的是“按位与”,不短路;而 && 是逻辑运算符,会跳过右侧求值。
- 只在明确需要按位操作时用
&、|、^,比如掩码计算、状态组合 - 条件判断一律用
&&/||,除非你刻意要强制执行两边(极少见) -
boolean类型参与&运算时,JVM 会把它当作 1-bit 整数处理,但语义已丢失,可读性差
用 & 和 | 实现权限掩码控制
权限系统里常用一个 int 存多个开关,每位代表一种权限。这时候 & 判断是否启用,| 启用新权限,~ 配合 & 清除某位。
- 定义权限常量必须是 2 的幂:
public static final int READ = 1 、<code>WRITE = 1 、<code>DELETE = 1 - 判断是否有 READ 权限:
(permissions & READ) != 0,不能写成(permissions & READ) == READ(虽然结果一样,但前者更直白且兼容 long) - 添加 WRITE 权限:
permissions |= WRITE;移除:permissions &= ~WRITE - 注意:如果权限值超过 32 位,改用
long并把常量改成1L ,否则高位被截断
^ 异或的两个关键用途:交换变量与翻转标志
^ 的核心特性是自反性:a ^ b ^ b == a。这带来两个实用场景,但都容易踩坑。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 不用临时变量交换两个整数:
a ^= b; b ^= a; a ^= b;—— 仅适用于int/long等基本类型,且a和b不能是同一变量引用(即swap(x, x)会让值变 0) - 翻转某个标志位:
flags ^= ENABLE_LOGGING;比flags = (flags & ~ENABLE_LOGGING) | (~flags & ENABLE_LOGGING)简洁得多 - 异或不适用于浮点数或对象,因为 IEEE 754 表示下
0.0 == -0.0但它们的 bit 模式不同,0.0 ^ -0.0编译不过
移位操作的陷阱:>>、>>> 和 的符号与溢出
左移 和右移容易被当成“乘除 2”,但实际是补 0 移位,和算术意义不完全等价;而负数右移尤其危险。
相当于乘以 2 的幂,但溢出不报错:<code>Integer.MAX_VALUE 得到负数,不是异常-
>>是带符号右移,负数高位补 1;>>>是无符号右移,高位永远补 0 —— 处理颜色值、网络字节序等纯二进制数据时,必须用>>> - 移位计数超过位宽会取模:
5 等价于 <code>5 即 <code>5 ,在 <code>long上是 %64 - 不要对负数用
>>做“向下取整除法”,比如-5 >> 1是 -3,而-5 / 2是 -2;该用除法就用除法
位运算不是炫技工具,它真实的价值在于资源受限场景下的紧凑表达和确定性行为。一旦涉及可读性妥协,就得问一句:这里真的需要位运算,还是只是习惯了敲 &?
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










