java中按位取反运算符~对操作数每一位(含符号位)翻转,结果按有符号补码解释,故~x恒等于-x-1;例如~5得-6,~-6得5,其本质是补码体系下的数学恒等式。

Java 中的按位取反运算符 ~ 对操作数的**每一位进行翻转(0 变 1,1 变 0)**,结果是该数的**补码形式下的按位取反值**,不是简单的“正变负、负变正”。理解它必须结合 Java 的整数表示方式——**有符号二进制补码(Two's Complement)**。
~ 运算的本质:对补码逐位取反
Java 中所有整数(byte/short/int/long)都以补码形式存储。~ 运算不关心数值大小或正负,只机械地将变量在内存中的所有位(包括符号位)全部翻转。
例如 int 类型占 32 位:
-
int a = 5; → 二进制补码(32位):
00000000 00000000 00000000 00000101 -
int b = ~a; → 每位取反:
11111111 11111111 11111111 11111010 - 这个结果仍是补码表示,需按补码规则解读:最高位为 1,说明是负数;其真值 = −(取反后加 1) = −(00000000 00000000 00000000 00000101 + 1) = −6
所以 ~5 == -6。同理:~-6 == 5,因为 −6 的补码取反后还原为 5。
为什么 ~x 等于 -x - 1?
这是补码体系下的恒等关系,可由定义推导:
- 对任意整数 x,其相反数 −x 的补码 = ~x + 1(即“取反加一”)
- 移项得:
~x = -x - 1
验证:
-
~0 = -0 - 1 = -1→ 正确(0 的补码全 0,取反全 1 → −1) ~100 = -100 - 1 = -101-
~-1 = -(-1) - 1 = 1 - 1 = 0→ 正确(−1 补码全 1,取反全 0)
注意位宽与类型扩展的影响
~ 运算作用于具体类型的位宽,结果类型与操作数相同。类型转换可能引发意外:
-
byte b = 1; → 实际存储为
00000001(8位) -
int i = ~b; → 先将 b 提升为 int(符号扩展):
00000000 00000000 00000000 00000001,再取反 →11111111 11111111 11111111 11111110= −2 - 若想只对低 8 位取反,需屏蔽高位:
(~b) & 0xFF→ 得到 254(无符号 byte 值)
实用技巧与常见用途
~ 在底层操作和算法中常用于:
-
设置掩码:如
~0xFF生成低 8 位为 0、其余为 1 的掩码(用于清零字节) -
判断奇偶性优化:
(x & 1) == 0判断偶数,等价于(~x & 1) == 1(较少用,但体现位逻辑) -
集合操作模拟:在用 int 表示 32 个标志位时,
~flags表示“所有未设置的位” -
快速取反加一的逆操作:需要
-x-1时直接写~x,语义更清晰
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











