java String intern

java String intern,第1张

在周志明的《深入理解java虚拟机》,2nd,p57中有一部分代码

String str1 = new StringBuilder("计算机").append("软件").toString();
System.out.println(str1.intern() == str1);

String str2 = new StringBuilder("ja").append("va").toString();
System.out.println(str2.intern() == str2);

对照着intern()看了api源码上的javadoc注释

/**
 * Returns a canonical representation for the string object.
 * 

* A pool of strings, initially empty, is maintained privately by the * class {@code String}. *

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

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

* All literal strings and string-valued constant expressions are * interned. String literals are defined in section 3.10.5 of the * The Java™ Language Specification. * * @return a string that has the same contents as this string, but is * guaranteed to be from a pool of unique strings. */ public native String intern();

个人理解是:

如果调用intern之前字符串已存在,返回字符串对象,否则返回字符串引用。“首次出现”返回引用。

讲到在jdk 7之前的版本中,intern() 会把首次遇到的String实例复制到永久代中,返回的是永久代中String实例的引用。由StringBuilder创建的String实例在堆上,所以不是同一个引用,返回false。

java虚拟机运行时数据区(jdk1.6及之前)

java虚拟机运行时数据区(jdk1.7)

 按照jdk历史版本的内存区域分布图,得知jdk 7之前的执行结果为

false
false

jdk 7及以后的执行结果为

true
false

 但是不太理解书籍里讲到的

“java”这个字符串在执行StringBuilder的toString()之前已经出现过,字符串常量池已经有它的引用了,不符合“首次出现”的原则。

感觉这里作者埋坑了,在看到3rd版里讲到这个地方,说读者有这个疑问,给了注释讲到说是在sun.misc.Version中已经存在,提到了知乎里的作者RednaxelaFX在https://www.zhihu.com/question/51102308/answer/124441115

里做了讲解, 讲的很好。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/756335.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-30
下一篇 2022-04-30

发表评论

登录后才能评论

评论列表(0条)

保存