关于String Pool的学习笔记

栏目: Java · 发布时间: 7年前

内容简介:前几天在「后端圈」群里,有位同学问了一个关于String s11 = new String(“11”);s11.intern();

前几天在「后端圈」群里,有位同学问了一个关于 java.lang.String#intern() 的问题:

String s11 = new String(“11”);

s11.intern();

String s12 = “11”;

System.out.println(s11 == s12);

请教下,应该输出true还是false?

在研究这个问题时,无意中,从问题中牵扯出来了对于一个概念的理解。

正文

大家看问题中的 String s12 = "11"; 这一段代码,这是一个很简单的字面量声明,经过「后端圈」群里兰大的指导,同时加上我自己的验证,我了解到,这个字符串字面量的声明会在编以后存储到 class 文件中的 class文件常量池 中。关于这一点可以用 javap -v 来印证:

关于String Pool的学习笔记

那么,就应该说明 String s12 = "11"; 这里的 11 这个字面量,会在 运行时常量池 生成时,被塞到其中。但是后来我看了一下 java.lang.String#intern() 的注释,里面有这样一段描述:

...
A pool of strings, initially empty, is maintained privately by the class {@code String}.
...
关于String Pool的学习笔记

看完这个,我就产生了一个疑问, java.lang.String#intern() 背后的这个 “Pool” 和 运行时常量池 是一回事吗?带着疑问,我又搜索了几篇文章,没找到答案。后来,在「JVM参数交流群」里提问得到了回复,根据笨神以及群里小伙伴‘蛋炒饭’、‘半拍’的回答,得出了结论,String Pool 和 运行时常量池,不是一回事。同时我还搜到了占小狼大大的一篇文章 「深入分析String.intern和String常量的实现原理」 在这篇文章的最后,阐述了 String Pool 和 运行时常量池的关系:

字符串常量一开始以Symbol类型表示,最终通过StringTable::intern方法生成字符串对象,并把字符串的真实引用更新到constantPool中,这样下次执行ldc指令时可以直接返回对象引用

通过这段描述,我简单的理解了一下字符串字面量在 堆、String Pool 和 Constant Pool 中存放的形式:可以理解为一个有两级缓存的结构。真实的字面量是放在堆中的,而 String Pool 可看作是一个全局一级缓存,里面缓存着堆上对应的真实字符串的引用,然后 Constant Pool 看作是各个 class 对应的二级缓存,里面存放着指向刚才 String Pool 里对应缓存内容的引用,也就是: Java中的字符串 -> Constant Pool 中缓存引用 -> String Pool 中缓存的引用 -> 堆中实际的字符串 这样一种结构。

当然,其实这里边还有很多细节我还没有理解,估计是需要看源码才能解得了,不过通过这次群里讨论了解到了一些概念层面的东西也不错,把原来模糊的概念了解的清晰起来了。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Java技术手册(第6版)

Java技术手册(第6版)

Benjamin J Evans、David Flanagan / 安道 / 人民邮电出版社 / 2015-12-1 / 79.00

《Java技术手册 第6版》为《Java 技术手册》的升级版,涵盖全新的Java 7 和Java 8。第1部分介绍Java 编程语言和Java 平台,主要内容有Java 环境、Java 基本句法、Java 面向对象编程、Java 类型系统、Java的面向对象设计、Java 实现内存管理和并发编程的方式。第2部分通过大量示例来阐述如何在Java 环境中完成实际的编程任务,主要内容有编程和文档约定,使......一起来看看 《Java技术手册(第6版)》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具