揭秘Java位运算:7大运算符详解 + 63%性能提升秘籍,解锁底层高效编程利器!

引言

Java位运算符直接操作二进制位(bit),适用于整数类型(byte, short, int, long, char),不兼容浮点数(float, double)。其核心价值在于底层计算优化高效算法实现(如位图、加密算法)。Java共支持7种位运算符

一、基本位运算符

1、按位与(&)

  • 规则:两操作数对应位均为1时结果为1,否则为0
    • 任何位与0相与结果为0(屏蔽效果
    • 任何位与1相与保留原值(透传效果
java 复制代码
int a = 60;         // 二进制: 0011 1100
int b = 13;         // 二进制: 0000 1101
int result = a & b; //  结果: 0000 1100 (十进制12)
  • 典型应用:掩码操作(提取特定位
java 复制代码
// 提取最低4位
int value = 0b10101100; // 原数值
int mask = 0b00001111;  // 掩码,表示只保留最低4位
int lowerNibble = value & mask; // 结果: 1100 (十进制12)

2、按位或(|)

  • 规则:两操作数对应位至少一个为1时结果为1
java 复制代码
int a = 60;         //  二进制:0011 1100
int b = 13;         //  二进制:0000 1101
int result = a | b; //   结果:0011 1101 (十进制61)
  • 典型应用:组合位标志
java 复制代码
final int READ    = 1;  // 0001 -> 表示读取权限
final int WRITE   = 2;  // 0010 -> 表示写入权限
final int EXECUTE = 4;  // 0100 -> 表示执行权限
final int OTHER   = 8;  // 1000 -> 表示其他权限

int permissions = READ | WRITE; // 0011 (3),表示 同时拥有读取和写入权限

3、按位异或(^)

  • 规则:两操作数对应位不同时结果为1,相同时为0
    • 归零律:a ^ a = 0
    • 恒等律:a ^ 0 = a
    • 交换律:a ^ b = b ^ a
    • 结合律:(a ^ b) ^ c = a ^ (b ^ c)
    • 可逆性:a ^ b ^ b = a(可应用于简单加密)
java 复制代码
int a = 60;         // 二进制:0011 1100
int b = 13;         // 二进制:0000 1101
int result = a ^ b; //  结果:0011 0001 (十进制49)
  • 典型应用:交换两个变量(无需临时变量)
java 复制代码
int x = 10, y = 20;
x = x ^ y;
// y转换为x值
y = x ^ y;  // y = (x^y)^y = x
// x转换位y值
x = x ^ y;  // x = (x^y)^x = y

4、按位取反(~)

  • 规则:翻转操作数的每一位,0→1, 1→0(包括符号位)
java 复制代码
int a = 5;       // 二进制:0000 0101
int result = ~a; // 结果: 1111 1010 (十进制-6,快速计算-a-1=-6)
  • 典型应用1:快速计算补码 - 负数的二进制表示
java 复制代码
// 手动计算补码(求负数的二进制表示)
int positive = 42; // 0010 1010
int negative = ~positive + 1; // 1101 0110 (补码形式)

System.out.println("+42: " + Integer.toBinaryString(positive)); // 0010 1010
System.out.println("-42: " + Integer.toBinaryString(negative)); // 1111 1111 1111 1111 1111 1111 1101 0110
  • 典型应用2:整数取反操作等价于:~x = -x - 1
java 复制代码
正数: 42 = 00000000 00000000 00000000 00101010
取反:~42 = 11111111 11111111 11111111 11010101 = -43

负数:   -42 = 11111111 11111111 11111111 11010110
取反:~(-42) = 00000000 00000000 00000000 00101001 = 41

二、移位运算符

1、左移(<<)

  • 规则:将二进制位向左移动指定位数,低位补0
  • 效果:相当于乘以 <math xmlns="http://www.w3.org/1998/Math/MathML"> 2 n 2^n </math>2n(n为移位位数)
  • 3<<4 等价于 <math xmlns="http://www.w3.org/1998/Math/MathML"> 3 × 2 4 3 \times 2^4 </math>3×24 => 48
  • -3<<4 等价于 <math xmlns="http://www.w3.org/1998/Math/MathML"> − 3 × 2 4 -3 \times 2^4 </math>−3×24 => -48

2、带符号右移(>>)

  • 规则:将二进制位向右移动高位补符号位(正数补0,负数补1)
  • 效果:相当于除以 <math xmlns="http://www.w3.org/1998/Math/MathML"> 2 n 2^n </math>2n(向下取整,相当于右侧溢出的位被丢弃)
  • 69>>4 等价于 <math xmlns="http://www.w3.org/1998/Math/MathML"> 69 ÷ 2 4 = 4.3125 69 \div 2^4 = 4.3125 </math>69÷24=4.3125 => 向下取整 => 4
  • -69>>4 等价于 <math xmlns="http://www.w3.org/1998/Math/MathML"> − 69 ÷ 2 4 = − 4.3125 -69 \div 2^4 = -4.3125 </math>−69÷24=−4.3125 => 向下取整 => -5

3、无符号右移(>>>)

  • 规则:右移时高位强制补0(负数可能变正数)
  • >>和>>>比较
    • 相同点:都是向下取整,右侧溢出的位被丢弃
    • 不同点:>>>处理结果都是非负数
  • 69>>>4 等价于 <math xmlns="http://www.w3.org/1998/Math/MathML"> 69 ÷ 2 4 = 4.3125 69 \div 2^4 = 4.3125 </math>69÷24=4.3125 => 向下取整 => 4
  • -69>>>4 结果:268435451

三、位运算高级技巧

1、高效乘除

java 复制代码
// 乘以2的n次方
int multiplyByPowerOfTwo = num << n; 

// 除以2的n次方(整数除法)
int divideByPowerOfTwo = num >> n; 

2、奇偶判断

java 复制代码
// 使用 &1 判断奇偶
boolean isEven = (num & 1) == 0; 

3. 快速取整(取模)

java 复制代码
// 对2的n次方取模(比%运算快5-10倍)
int mod = value & ((1 << n) - 1);

// 对256取模
int mod256 = value & 0xFF;  // 十六进制0xFF => 二进制1111 1111  ==> 十进制255

// 对32取模
int mod32 = value & 0x1F;   // 十六进制0x1F => 二进制0001 1111  ==> 十进制31

4、位标志管理

java 复制代码
// 定义标志位
final int FLAG_A = 1 << 0; // 二进制0001,十进制1
final int FLAG_B = 1 << 1; // 二进制0010,十进制2
final int FLAG_C = 1 << 2; // 二进制0100,十进制4

// 设置标志
int flags = FLAG_A | FLAG_C; // 二进制0101,十进制5

// 检查标志
boolean hasFlagB = (flags & FLAG_B) != 0; // 0101 & 0010 = 0000

// 清除标志
flags &= ~FLAG_A; // 0101 & 1110 = 0100 结果对应FLAG_C,去掉了FLAG_A

四、性能对比实验

  • 奇偶判断,传统方式与位运算方式性能比较(单位:亿次)
java 复制代码
// 测试一亿次
int iterations = 100000000;

// 传统方式
long start = System.nanoTime();
for (int i = 0; i < iterations; i++) {
    boolean result = (i % 2) == 0;
}
long modTime = System.nanoTime() - start;

// 位运算方式
start = System.nanoTime();
for (int i = 0; i < iterations; i++) {
    boolean result = (i & 1) == 0;
}
long bitTime = System.nanoTime() - start;

System.out.println("取模方式: " + modTime + " ns");
System.out.println("位运算方式: " + bitTime + " ns");
System.out.println("性能提升: " + (modTime - bitTime) * 100 / modTime + "%");

典型测试结果:

java 复制代码
取模方式: 2188666 ns
位运算方式: 789709 ns
性能提升: 63%

五、注意事项

1、左移位位数的有效范围

  • 官方规定:实际移位位数:对 int 取模 32,对 long 取模 64
  • 理论int左移32位没有意义,所有位都被挤出去了,结果是 0
java 复制代码
int x = 3;
x << 32; // 等价于 x << 0 (结果仍是 3)
x << 33; // 等价于 x << 1 (结果为 6)

2、运算符优先级陷阱

  • 位运算符优先级低于比较运算符(如 ==>)和算术运算符(+-
  • 建议:始终用 () 明确优先级
java 复制代码
int a = 5, b = 3, c = 2;
int r1 = a & b + c;   // 等价于 a & (b + c) = 5 & 5 = 5
int r2 = (a & b) + c; // (5 & 3) + 2 = 1 + 2 = 3

结语

位运算符是Java高效编程的秘密武器。它们不仅提供接近硬件的操作能力,还能在算法优化内存管理网络通信等场景发挥关键作用。虽然现代JVM已高度优化,但在性能敏感领域(如高频交易、游戏引擎、大数据处理),合理使用位运算仍能带来显著提升。

黄金法则:当你在处理二进制数据、标志位集合或需要极致性能时,位运算应是首选工具。但在常规业务逻辑中,优先选择可读性更高的标准操作

相关推荐
喵手10 分钟前
StringUtils 工具类实战详解,你还不进来学习!
java·后端·java ee
喵手13 分钟前
如何快速实现文件上传、下载与读写操作?FileUtils有话要说~
java·后端·java ee
DongLi0116 分钟前
Rust 变量和可变性
后端
陈随易37 分钟前
一段时间没写文章了,花了10天放了个屁
前端·后端·程序员
星星电灯猴40 分钟前
抓包工具分析接口跳转异常:安全校验误判 Bug 全记录
后端
调试人生的显微镜41 分钟前
后台发热、掉电严重?iOS 应用性能问题实战分析全过程
后端
深栈解码1 小时前
OpenIM 源码深度解析系列(十八):附录二数据库结构
后端
前端付豪1 小时前
Google Ads 广告系统排序与实时竞价架构揭秘
前端·后端·架构
努力的小郑1 小时前
MySQL DATETIME类型存储空间详解:从8字节到5字节的演变
后端
哪吒编程2 小时前
我的第一个AI编程助手,IDEA最新插件“飞算JavaAI”,太爽了
java·后端·ai编程