Java的StringPool是存放在方法区中,是所有类共享的吗?
巴扎黑
巴扎黑 2017-04-17 11:16:07
0
4
933

Java虚拟机中,每个类都有一个常量池,StringPool存在常量池中,对于A.StringA.intern()==B.StringB.intern()应该返回False~~可是我打出来的是True,Why?

巴扎黑
巴扎黑

全部回复(4)
阿神

每个类中的常量池:

java的每一个类都有一个常量池,这个常量池定义在.class文件中有描述,包括整形、浮点型、字符串、类名、属性名、方法声明等。在jvm装载.class文件时,会装载这些常量池信息,并按照JMM(java存储模型)的定义,在方法区(即常说的PermGen Space[永久代])中开辟一块内存空间,用以存储这些常量。

需要注意的是:

java同时会在方法区维持一个string pool,在装载常量池的字符串型常量时,会先将这些字符串常量存储到string pool中,然后返回其引用给每个类的常量池。

至于String.intern()方法,引用其JavaDoc:

A pool of strings, initially empty, is maintained privately by the class String.

When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the {@link #equals(Object)} method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.

It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true.

加粗标明的行也说明了java在方法区中会维持string pool。至于为什么

A.StringA.intern()==B.StringB.intern()会返回true

相信你看了javaDoc会明白。

PS:不光String类有JVM原生支持的常量池,Boolean、Byte、Character、Short、Integer、Long这六种原始类型包装类,也实现了代码级的常量池,具体可参考JDK源码。
PPS:可供参考常量池

阿神

Java Doc:

"When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned. "

就是说, 在调用str.intern()时, 首先去pool中找是否有 equals(str)==true的字符串. 找到后返回已存在于pool里的字符串, 否则把str加入pool中.

所以在pool里, 相等的字符串 只会有一份.

刘奇

可能我问题有点问题~,“运行时常量池是方法去的一部分,Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息就是常量池,用于存放编译器生成的各种字面量和符号引用,这部分内容在类加载后存放在方法区的运行时常量池中。”具体答案知道了~class文件信息中的常量池只是对运行时常量池的一个引用

伊谢尔伦

如果字符串StringA和StringB有着相同的内容,那么上面的语句StringA.intern()==StringB.intern()为true,因为他们指向的为同一个对象。

调用intern后,首先检查字符串常量池中是否有该对象的引用,如果存在,则将这个引用返回给变量,否则将引用加入并返回给变量。

具体可以参考Java中的字符串常量池

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板