Java基础系列文章
Java位运算符直接操作二进制位(bit),适用于整数类型(byte, short, int, long, char),不兼容浮点数(float, double)。其核心价值在于底层计算优化和高效算法实现(如位图、加密算法)。Java共支持7种位运算符。
均为1时结果为1,否则为0 屏蔽效果)透传效果)int a = 60; // 二进制: 0011 1100
int b = 13; // 二进制: 0000 1101
int result = a & b; // 结果: 0000 1100 (十进制12)提取特定位)// 提取最低4位
int value = 0b10101100; // 原数值
int mask = 0b00001111; // 掩码,表示只保留最低4位
int lowerNibble = value & mask; // 结果: 1100 (十进制12)至少一个为1时结果为1int a = 60; // 二进制:0011 1100
int b = 13; // 二进制:0000 1101
int result = a | b; // 结果:0011 1101 (十进制61)组合位标志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),表示 同时拥有读取和写入权限不同时结果为1,相同时为0 a ^ a = 0a ^ 0 = aa ^ b = b ^ a(a ^ b) ^ c = a ^ (b ^ c)a ^ b ^ b = a(可应用于简单加密)int a = 60; // 二进制:0011 1100
int b = 13; // 二进制:0000 1101
int result = a ^ b; // 结果:0011 0001 (十进制49)交换两个变量(无需临时变量)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 = y0→1, 1→0(包括符号位)int a = 5; // 二进制:0000 0101
int result = ~a; // 结果: 1111 1010 (十进制-6,快速计算-a-1=-6)// 手动计算补码(求负数的二进制表示)
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~x = -x - 1正数: 42 = 00000000 00000000 00000000 00101010
取反:~42 = 11111111 11111111 11111111 11010101 = -43
负数: -42 = 11111111 11111111 11111111 11010110
取反:~(-42) = 00000000 00000000 00000000 00101001 = 41向左移动指定位数,低位补0(n为移位位数)
3<<4 等价于 => 48

-3<<4 等价于 => -48

向右移动,高位补符号位(正数补0,负数补1)(向下取整,相当于右侧溢出的位被丢弃)
69>>4 等价于 => 向下取整 => 4

-69>>4 等价于 => 向下取整 => -5

高位强制补0(负数可能变正数)向下取整,右侧溢出的位被丢弃非负数69>>>4 等价于 => 向下取整 => 4

-69>>>4 结果:268435451

// 乘以2的n次方
int multiplyByPowerOfTwo = num << n;
// 除以2的n次方(整数除法)
int divideByPowerOfTwo = num >> n; // 使用 &1 判断奇偶
boolean isEven = (num & 1) == 0; // 对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// 定义标志位
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// 测试一亿次
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 + "%");典型测试结果:
取模方式: 2188666 ns
位运算方式: 789709 ns
性能提升: 63%int 取模 32,对 long 取模 64没有意义,所有位都被挤出去了,结果是 0int x = 3;
x << 32; // 等价于 x << 0 (结果仍是 3)
x << 33; // 等价于 x << 1 (结果为 6)低于比较运算符(如 ==、>)和算术运算符(+、-)() 明确优先级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已高度优化,但在性能敏感领域(如高频交易、游戏引擎、大数据处理),合理使用位运算仍能带来显著提升。
黄金法则:当你在处理二进制数据、标志位集合或需要极致性能时,位运算应是首选工具。但在常规业务逻辑中,优先选择可读性更高的标准操作