<p>按位取反(~)在Java中对整数补码的每一位翻转,满足恒等式 ~x == -x - 1;以 int x = 5 为例,~5 得 -6;对 byte 等小类型会先提升为 int 运算,结果需强转才得对应类型值。</p>

按位取反(~)在 Java 中是对整数的**每一位二进制位进行翻转**(0 变 1,1 变 0),它作用于补码表示的整数,因此结果不等于简单的“变号”或“减一”,需结合补码规则理解。关键点是:Java 中所有整数(byte、short、int、long)均以**补码形式存储**,而 ~x 的数学等价式为:~x == -x - 1。
为什么 ~x 等于 -x - 1?
这是由补码定义决定的:
- 一个负数
-x的补码 =~x + 1(即先按位取反,再加 1); - 两边同时减 1 得:
~x = -x - 1; - 该公式对所有有符号整数类型(包括
int)都成立,前提是运算不溢出(但按位取反本身不会溢出,只是改变值)。
以 int 类型为例的手动计算步骤
以 int x = 5 为例(32 位):
- 5 的二进制原码(正数):00000000 00000000 00000000 00000101;
- 补码同原码(正数补码 = 原码);
- 按位取反
~5:11111111 11111111 11111111 11111010; - 该结果是负数补码,还原成十进制:先取反得 00000000 00000000 00000000 00000101,再加 1 → 00000000 00000000 00000000 00000110 = 6,所以原数为 -6;
- 验证公式:
-5 - 1 = -6✅。
注意数据类型与截断影响
当对较小类型(如 byte)使用 ~ 时,Java 会先将其**提升为 int 再运算**,结果仍是 int:
立即学习“Java免费学习笔记(深入)”;
-
byte b = 1;→~b实际计算的是~((int)b)=~1=-2; - 若想得到 byte 范围内的结果,需手动强转:
(byte)~b→(byte)-2=0xFE(即 -2 的 byte 表示); - 直接打印
(byte)~b仍输出 -2,因为byte输出时自动符号扩展为 int 显示。
常见误区提醒
不要误以为 ~x 是“绝对值取反”或“逻辑非”:
-
~0=-1(不是 0 或 1); -
~-1=0(因为-(-1) - 1 = 0); -
~是位运算符,操作对象是二进制位,和布尔表达式中的!(逻辑非)完全不同; - 对无符号概念(如
char)使用~:虽然char是 16 位无符号,但~c仍会提升为 int 并按补码规则计算,结果可能为负。










