
在 Java 的 Map 中放入 true/false 等基本类型字面量时,JVM 会复用 Boolean.TRUE 和 Boolean.FALSE 静态实例,不会每次新建对象;同理,Integer 等小范围整数(-128 ~ 127)也享受缓存优化,装箱开销极低。
在 java 的 `map
当你向 Map<string object></string>(如 myMap.put(MY_FLAG_NAME, true))插入一个布尔字面量时,Java 编译器会自动执行自动装箱(autoboxing),即把 boolean 转为 Boolean 对象。但关键在于:这并非每次都调用 new Boolean(...)。
根据 Java 语言规范 §5.1.7,对常量布尔表达式(如字面量 true、false)的装箱,必须保证结果引用同一对象。也就是说:
myMap.put("flag", true); // ✅ 实际等价于 Boolean.valueOf(true)
myMap.put("flag", false); // ✅ 实际等价于 Boolean.valueOf(false)而 Boolean.valueOf(boolean) 的实现极为轻量:
public static Boolean valueOf(boolean b) {
return b ? TRUE : FALSE; // 直接返回静态 final 字段
}Boolean.TRUE 和 Boolean.FALSE 是 JVM 启动时就初始化好的单例对象,整个生命周期中仅存在两个 Boolean 实例——无论你调用 put(..., true) 百万次,都只是复用同一个 Boolean.TRUE 引用。
立即学习“Java免费学习笔记(深入)”;
✅ 同理适用于其他包装类的缓存机制:
-
Integer.valueOf(int)缓存-128至127(可由-Djava.lang.Integer.IntegerCache.high=xxx扩展) -
Character.valueOf(char)缓存'\u0000'到'\u007f' -
Byte.valueOf(byte)、Short.valueOf(short)全范围缓存(因值域小)
⚠️ 注意事项:
- 若使用
new Boolean(true)(显式构造),则必然创建新对象,破坏缓存语义,应绝对避免; - 非常量表达式(如
myMap.put("flag", x > 0))虽不被 JLS 强制要求复用,但主流 JDK(OpenJDK/HotSpot)仍通过valueOf实现,实际行为一致; -
null方案(方案2)虽无装箱开销,但语义模糊(“键存在但值为 null” vs “键不存在”),且containsKey()无法区分 flag 是否显式设为false; - 字符串复用方案(方案3)看似“零装箱”,但引入了额外语义耦合(用字符串值表示布尔逻辑),可读性与维护性下降,且
String对象本身也有内存成本。
? 总结建议:
首选 myMap.put(key, true/false) —— 语义清晰、零额外对象分配、JVM 级别优化成熟。在高频调用场景下,其性能与 null 或字符串方案无实质差异,且代码意图一目了然。真正的性能瓶颈更可能来自 Map 结构本身(如哈希冲突、扩容)、GC 压力或业务逻辑,而非布尔装箱。优化前请先用 JMH 进行实测,而非过早纠结于已被充分优化的语言机制。



















