在 Java 中,按位运算符对整数数据的单个位进行操作。这里的整数数据包括 byte
、short
、int
和 long
类型的数据。
Java 中有 7 个运算符用于执行位级操作。
1. Java 按位 OR 运算符
按位 OR |
运算符在至少一个操作数为 1 时返回 1。否则,它返回 0。
以下真值表演示了按位 OR 运算符的工作原理。令 a 和 b 为两个只能取二进制值(即 1 或 0)的操作数。
a | b | a | b |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
上表称为按位 OR 运算符的“真值表”。
让我们看一看整数 12 和 25 的按位 OR 操作。
12 = 00001100 (In Binary)
25 = 00011001 (In Binary)
Bitwise OR Operation of 12 and 25
00001100
| 00011001
____________
00011101 = 29 (In Decimal)
示例 1:按位 OR
class Main {
public static void main(String[] args) {
int number1 = 12, number2 = 25, result;
// bitwise OR between 12 and 25
result = number1 | number2;
System.out.println(result); // prints 29
}
}
2. Java 按位 AND 运算符
按位 AND &
运算符当且仅当两个操作数都为 1 时返回 1。否则,它返回 0。
下表演示了按位 AND 运算符的工作原理。令 a 和 b 为两个只能取二进制值(即 1 和 0)的操作数。
a | b | a & b |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
让我们来看一看整数 12 和 25 的按位 AND 操作。
12 = 00001100 (In Binary)
25 = 00011001 (In Binary)
// Bitwise AND Operation of 12 and 25
00001100
& 00011001
____________
00001000 = 8 (In Decimal)
示例 2:按位 AND
class Main {
public static void main(String[] args) {
int number1 = 12, number2 = 25, result;
// bitwise AND between 12 and 25
result = number1 & number2;
System.out.println(result); // prints 8
}
}
3. Java 按位 XOR 运算符
按位 XOR ^
运算符当且仅当其中一个操作数为 1 时返回 1。但是,如果两个操作数都为 0 或都为 1,则结果为 0。
以下真值表演示了按位 XOR 运算符的工作原理。令 a 和 b 为两个只能取二进制值(即 1 或 0)的操作数。
a | b | a ^ b |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
让我们看一看整数 12 和 25 的按位 XOR 操作。
12 = 00001100 (In Binary)
25 = 00011001 (In Binary)
// Bitwise XOR Operation of 12 and 25
00001100
^ 00011001
____________
00010101 = 21 (In Decimal)
示例 4:按位 XOR
class Main {
public static void main(String[] args) {
int number1 = 12, number2 = 25, result;
// bitwise XOR between 12 and 25
result = number1 ^ number2;
System.out.println(result); // prints 21
}
}
4. Java 按位补码运算符
按位补码运算符是一个一元运算符(仅作用于一个操作数)。它用 ~
表示。
它将二进制数字 **1** 变为 **0**,将 **0** 变为 **1**。

需要注意的是,任何整数 **N** 的按位补码都等于 **- (N + 1)**。例如,
考虑整数 **35**。根据规则,35 的按位补码应该是 **-(35 + 1)** = **-36**。现在让我们看看是否能得到正确答案。
35 = 00100011 (In Binary)
// using bitwise complement operator
~ 00100011
__________
11011100
在上面的示例中,我们得到 35 (00100011
) 的按位补码是 11011100
。这里,如果我们把结果转换为十进制,我们得到 220。
然而,需要注意的是,我们不能直接将结果转换为十进制并得到期望的输出。这是因为二进制结果 11011100
也等同于 -36。
为了理解这一点,我们首先需要计算 **-36** 的二进制输出。
2 的补码
在二进制算术中,我们可以使用 2 的补码来计算整数的二进制负数。
1 的补码将 **0** 变为 **1**,将 **1** 变为 **0**。而且,如果我们给 1 的补码结果加 1,我们就得到了原始数字的 2 的补码。例如,
// compute the 2's complement of 36
36 = 00100100 (In Binary)
1's complement = 11011011
2's complement:
11011011
+ 1
_________
11011100
在这里,我们可以看到 36(即 **-36**)的 2 的补码是 11011100
。这个值等同于 35 的按位补码。
因此,我们可以说 35 的按位补码是 **-(35 + 1) = -36**。
示例 3:按位补码
class Main {
public static void main(String[] args) {
int number = 35, result;
// bitwise complement of 35
result = ~number;
System.out.println(result); // prints -36
}
}
Java 移位运算符
Java 中有三种移位运算符
- 带符号左移 (<<)
- 带符号右移 (>>)
- 无符号右移 (>>>)
5. Java 左移运算符
左移运算符将所有位向左移动指定的位数。它用 <<
表示。

从上图可以看出,我们有一个 4 位数字。当我们在它上面执行 1 位左移操作时,每个单独的位都向左移动 **1** 位。
结果是,最左边的位(最高有效位)被丢弃,最右边的位置(最低有效位)保持空。这个空位用 **0** 填充。
示例 5:左移运算符
class Main {
public static void main(String[] args) {
int number = 2;
// 2 bit left shift operation
int result = number << 2;
System.out.println(result); // prints 8
}
}
5. Java 带符号右移运算符
带符号右移运算符将所有位向右移动指定的位数。它用 >>
表示。
当我们向右移动任何数字时,最低有效位(最右边)被丢弃,最高有效位(最左边)用符号位填充。例如,
// right shift of 8
8 = 1000 (In Binary)
// perform 2 bit right shift
8 >> 2:
1000 >> 2 = 0010 (equivalent to 2)
这里,我们正在进行 8 的右移(即符号为正)。因此,没有符号位。所以最左边的位用 **0** 填充(表示正号)。
// right shift of -8
8 = 1000 (In Binary)
1's complement = 0111
2's complement:
0111
+ 1
_______
1000
Signed bit = 1
// perform 2 bit right shift
8 >> 2:
1000 >> 2 = 1110 (equivalent to -2)
在这里,我们使用了带符号位 **1** 来填充最左边的位。
示例 6:带符号右移运算符
class Main {
public static void main(String[] args) {
int number1 = 8;
int number2 = -8;
// 2 bit signed right shift
System.out.println(number1 >> 2); // prints 2
System.out.println(number2 >> 2); // prints -2
}
}
7. Java 无符号右移运算符
Java 还提供无符号右移。它用 >>>
表示。
这里,空的最左边位置用 **0** 填充,而不是符号位。例如,
// unsigned right shift of 8
8 = 1000
8 >>> 2 = 0010
// unsigned right shift of -8
-8 = 1000 (see calculation above)
-8 >>> 2 = 0010
示例 7:无符号右移
class Main {
public static void main(String[] args) {
int number1 = 8;
int number2 = -8;
// 2 bit signed right shift
System.out.println(number1 >>> 2); // prints 2
System.out.println(number2 >>> 2); // prints 1073741822
}
}
正如我们所见,带符号和无符号右移运算符对负位返回不同的结果。要了解更多信息,请访问 >> 和 >>> 之间的区别。