基本类型字面量(如42)编译期写入class常量池,但基本类型本身不进常量池;包装类(Byte至Character等)在堆中预缓存[-128,127]范围对象,Boolean缓存true/false,Float/Double不缓存。

基本类型本身不进常量池,只有字面量参与编译期优化
Java 的 基本类型(如 int、char、boolean)不是对象,不存于常量池中。它们直接以值的形式存储在栈或堆(如成员变量)里。但它们的字面量(literal)会在编译时被写入 class 文件的常量池,比如代码中出现的 int x = 42;,其中 42 会作为 CONSTANT_Integer 类型的常量项,记录在 class 的常量池结构里——这只是编译期的静态描述,不等于运行时“共享对象”。
包装类常量池是运行时缓存,有明确范围限制
Byte、Short、Integer、Long、Character 这五种包装类在 JVM 启动时,会**预先缓存一部分常用值的对象引用**,存放在堆中的一个专用缓存区(常被通俗称为“包装类常量池”,实际是类内部的静态数组,如 Integer.IntegerCache.cache)。
- 默认缓存范围是 [-128, 127](可由 JVM 参数调整,如
-XX:AutoBoxCacheMax=200) - 超出该范围时,每次调用
valueOf()都会新建对象,不再复用 -
Boolean缓存true和false;Float和Double不做缓存
例如:Integer a = 100; Integer b = 100; → a == b 为 true(都指向缓存中同一个对象)Integer c = 200; Integer d = 200; → c == d 为 false(各自 new 出新对象)
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
字符串常量池与包装类缓存机制不同,但目标一致
字符串常量池(String Constant Pool)位于堆中(JDK 7+),用于复用相同内容的 String 实例;而包装类缓存是类级别的静态结构,两者物理位置和实现方式不同,但都服务于同一目的:避免重复创建相同语义的对象,节省内存和提升性能。
- 二者都不影响自动装箱/拆箱行为:写
int i = 5;或Integer j = 5;,编译器都会转成Integer.valueOf(5) - 二者都只对“直接赋值”或
valueOf()生效;用new Integer(5)总是新建对象,绕过缓存
判断是否共享,关键看创建方式和取值范围
不要依赖 == 比较包装类值是否相等——它比较的是引用是否相同,而引用是否相同取决于是否命中缓存。
- 安全做法:数值比较一律用
.equals()(注意空指针) - 想确认是否复用:可用
System.identityHashCode()查看底层对象地址哈希 - 调试技巧:配合 JVM 参数
-XX:+PrintStringTableStatistics或-XX:+UnlockDiagnosticVMOptions观察缓存状态
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










