1. 概述

在 Java 中,运算符用于对数据和变量进行操作。Java 提供了多种类型的运算符,包括算术、关系、逻辑、赋值以及位运算符(Bitwise Operators)

本篇文章将深入讲解 Java 中的位运算符,包括其工作原理、分类和实际应用。

2. 位运算符简介

位运算符直接操作整数类型的二进制位,适用于 longintshortcharbyte 类型。

它们的工作流程如下:

  1. 将操作数转换为二进制形式
  2. 对每一位按照运算符规则进行操作
  3. 最后将结果转换回十进制

举个例子:

int value1 = 6;
int value2 = 5;

执行如下位运算:

int result = 6 | 5;

对应的二进制表示为:

value1 = 0110
value2 = 0101

进行 OR 运算后:

0110
0101
-----
0111

结果 0111 转换回十进制就是 7

位运算符分类

位运算符可以分为两大类:

  • 位逻辑运算符:AND、OR、XOR、NOT
  • 位移运算符:左移、右移、无符号右移

接下来我们逐个来看。

3. 位逻辑运算符

3.1. 位或运算(|)

OR 运算符对两个整数的每一位进行比较,只要有一个为 1,则结果为 1。

这与布尔逻辑中的 || 类似。

示例代码:

@Test
public void givenTwoIntegers_whenOrOperator_thenNewDecimalNumber() {
    int value1 = 6;
    int value2 = 5;
    int result = value1 | value2;
    assertEquals(7, result);
}

二进制运算过程:

0110
0101
-----
0111

3.2. 位与运算(&)

AND 运算符对两个整数的每一位进行比较,只有当两个位都为 1 时,结果才为 1。

类似于布尔逻辑中的 &&

示例代码:

@Test
public void givenTwoIntegers_whenAndOperator_thenNewDecimalNumber() {
    int value1 = 6;
    int value2 = 5;
    int result = value1 & value2;
    assertEquals(4, result);
}

二进制运算过程:

0110
0101
-----
0100

结果为十进制 4

3.3. 位异或运算(^)

XOR 运算符比较两个整数的每一位,如果不同则为 1,相同则为 0。

示例代码:

@Test
public void givenTwoIntegers_whenXorOperator_thenNewDecimalNumber() {
    int value1 = 6;
    int value2 = 5;
    int result = value1 ^ value2;
    assertEquals(3, result);
}

二进制运算过程:

0110
0101
-----
0011

结果为十进制 3

3.4. 位取反运算(~)

取反运算符对整数的每一位进行翻转,0 变 1,1 变 0。

⚠️ 注意:Java 中整数采用补码形式存储,因此取反后的结果会是一个负数。

示例代码:

@Test
public void givenOneInteger_whenNotOperator_thenNewDecimalNumber() {
    int value1 = 6;
    int result = ~value1;
    assertEquals(-7, result);
}

运算过程如下:

value1 = 0000 0110
~value1 = 1111 1001

由于最高位为 1,表示负数,因此需要进一步计算补码:

1111 1001 -> 0000 0110 + 1 -> 0000 0111 = 7

最终结果为 -7

3.5. 位运算符真值表

A B A|B A&B A^B ~A
0 0 0 0 0 1
1 0 1 0 1 0
0 1 1 0 1 1
1 1 1 1 0 0

4. 位移运算符

位移运算符用于将整数的所有位向左或向右移动指定的位数。

语法如下:

value <operator> <number_of_times>

4.1. 有符号左移(<<)

左移运算符将所有位向左移动,右侧空位补 0。

⚠️ 每左移一位相当于乘以 2,左移 n 位相当于乘以 2^n。

示例:

@Test
public void givenOnePositiveInteger_whenLeftShiftOperator_thenNewDecimalNumber() {
    int value = 12;
    int leftShift = value << 2;
    assertEquals(48, leftShift);
}

二进制表示:

12 = 00001100
<<2 = 00110000 = 48

负数同样适用:

@Test
public void givenOneNegativeInteger_whenLeftShiftOperator_thenNewDecimalNumber() {
    int value = -12;
    int leftShift = value << 2;
    assertEquals(-48, leftShift);
}

4.2. 有符号右移(>>)

右移运算符将所有位向右移动,左侧空位根据符号位填充。

  • 正数补 0
  • 负数补 1

示例:

@Test
public void givenOnePositiveInteger_whenSignedRightShiftOperator_thenNewDecimalNumber() {
    int value = 12;
    int rightShift = value >> 2;
    assertEquals(3, rightShift);
}

二进制表示:

12 = 00001100
>>2 = 00000011 = 3

负数示例:

@Test
public void givenOneNegativeInteger_whenSignedRightShiftOperator_thenNewDecimalNumber() {
    int value = -12;
    int rightShift = value >> 2;
    assertEquals(-3, rightShift);
}

4.3. 无符号右移(>>>)

无符号右移不管正负,左侧空位一律补 0。

示例(正数):

@Test
public void givenOnePositiveInteger_whenUnsignedRightShiftOperator_thenNewDecimalNumber() {
    int value = 12;
    int unsignedRightShift = value >>> 2;
    assertEquals(3, unsignedRightShift);
}

负数示例:

@Test
public void givenOneNegativeInteger_whenUnsignedRightShiftOperator_thenNewDecimalNumber() {
    int value = -12;
    int unsignedRightShift = value >>> 2;
    assertEquals(1073741821, unsignedRightShift);
}

5. 位运算符与逻辑运算符的区别

特性 位运算符 逻辑运算符
操作对象 二进制位(整数) 布尔表达式
返回值类型 整数 boolean
短路特性 无(总是计算两边) 有(如 &&、
使用场景 位操作、底层控制 条件判断

6. 实际应用场景

位运算符虽然看起来“底层”,但其实际用途非常广泛:

  • 通信协议解析:处理数据包头部的标志位
  • 嵌入式开发:精确控制寄存器中的某一位
  • 加密算法:如 XOR 用于简单加密
  • 数据压缩:通过位操作减少存储空间

7. 总结

本文全面介绍了 Java 中的位运算符及其使用方式,包括逻辑运算和位移运算,并通过示例说明了它们在实际开发中的应用场景。

虽然位运算在日常业务开发中使用频率不高,但在性能敏感、底层控制、协议解析等场景中却非常实用。

所有示例代码均可在 GitHub 上获取:https://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-lang-operators


原始标题:Java Bitwise Operators