Java位运算仅支持基本整数类型,包装类需自动拆箱;高效做法是全程用基本类型运算,仅必要时装箱,并善用缓存(如Integer -128~127)。

Java 中基本类型直接支持位运算,包装类则需先拆箱;高效处理的关键是避免无谓装箱、善用缓存、优先使用基本类型参与运算。
位运算必须用基本类型
Java 的位运算符(&、|、^、~、、>>、>>>)只定义在基本整数类型(byte、short、int、long)上。包装类如 Integer 本身不重载这些运算符,不能直接写 new Integer(5) & new Integer(3) —— 编译会报错。
实际使用时,JVM 会自动触发拆箱:只要表达式中出现包装类参与位运算,就会隐式调用 intValue() 等方法转为基本类型。例如:
Integer a = 6; Integer b = 11; int result = a & b; // 自动拆箱为 int,再执行 &
立即学习“Java免费学习笔记(深入)”;
避免高频装箱带来的性能损耗
虽然拆箱是自动的,但若反复创建新包装对象(尤其在循环或高频逻辑中),会带来额外对象分配和 GC 压力。以下写法不推荐:
- 在循环内用
Integer.valueOf(i)构造大量新对象再做位运算 - 将位运算结果又用
Integer.valueOf()包装回去,仅为了后续传参(除非接口明确要求引用类型) - 用
new Integer(x)—— 已废弃,且绕过缓存,完全不必要
更高效的做法是:中间计算全程用 int 或 long,仅在必须传递包装类(如泛型容器、反射调用、API 参数)时才做一次装箱。
合理利用缓存机制减少对象创建
Byte、Short、Integer、Long 和 Character 对常用小值做了缓存(如 Integer 是 -128 ~ 127)。这意味着:
- 对这个范围内的值,用
Integer.valueOf(100)比new Integer(100)快且省内存 - 但位运算本身不依赖缓存——缓存只影响对象复用,不影响运算速度
- 超出缓存范围(如
Integer.valueOf(200))仍会新建对象,此时应考虑是否真需要包装类
注意:Float 和 Double 没有缓存,Boolean 虽有 TRUE/FALSE 单例,但不支持位运算(boolean 类型本身也不支持 & 等运算符,只有逻辑运算 &&)。
典型高效写法示例
假设要批量提取一组整数的低 4 位(即掩码 0xF):
- ✅ 推荐(基本类型主导):
int[] raw = {...}; int[] low4 = Arrays.stream(raw).map(x -> x & 0xF).toArray(); - ⚠️ 可接受(缓存内值 + 显式拆箱):
List<integer> list = ...; list.stream().mapToInt(Integer::intValue).map(x -> x & 0xF).boxed().collect(...);</integer> - ❌ 避免:
list.stream().map(i -> i & 0xF).map(Integer::valueOf).collect(...)—— 多余装箱


















