查阅很多资料、文章摘要自己总结的,有错误欢迎指正
创建时期 | 存储内容 | 底层存储机制 | 备注 | |
---|---|---|---|---|
class常量池 | 编译期 | 编译器生成的各种字面量和符号引用 | 静态文件 | 每个类独有 |
运行时常量池 | 类加载时 | 将class常量池的内容加载进来 | 存储在方法区(底层实现:jdk1.8前永久代,之后元空间,机器的直接内存) | 每个类独有 |
字符串常量池 | 未从得知 | 字符串值和引用 | StringTable类,底层为一个Hash表 jdk1.7前存储在方法区,之后转移到堆中 | JVM全局唯一 |
字面量(文本字符串、被声明为final的常量<基于jvm的编译优化:包括final值+final值的结果>、基本数据类型的值)
符号引用(类和接口的全限定名、字段的名称和描述符、方法的名称和描述符)
关于字符串常量池何时创建
字符串常量池同其它六种基本类型的常量池一样,是jvm的一种缓存机制。主要为了避免重复创建,节省空间;支持引用==比较是否相等,节省时间。由此推论它的创建基于jvm,可能在第一个字符串出现时创建,也可能在jvm加载的时候创建。
关于编译期和运行期
编译期就是将java文件生成二进制class的过程
运行期包括类的加载
网上有很多资料说到 运行时常量池存储编译期产生的字面量和符号引用,这句话是没问题的。只是我个人理解在编译期就将字面量和符号引用放入运行时常量池偏差,其实是编译期放入class文件常量池,在类加载阶段将class文件常量池内容加载入运行时常量池
关于string.intern()方法
运行期动态往常量池中动态添加字符串引用,这个常量池指的是字符串常量池。
两篇写的不错的相关文章向大家推荐:
https://www.jianshu.com/p/8966c51e9728
https://blog.csdn.net/q5706503/article/details/84640762
转载请标明出处!