java String intern() 方法学习笔记

28 篇文章 0 订阅

在周志明的《深入理解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.
 * <p>
 * A pool of strings, initially empty, is maintained privately by the
 * class {@code String}.
 * <p>
 * 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.
 * <p>
 * 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}.
 * <p>
 * All literal strings and string-valued constant expressions are
 * interned. String literals are defined in section 3.10.5 of the
 * <cite>The Java&trade; Language Specification</cite>.
 *
 * @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 6中,intern() 会把首次遇到的字符串实例复制到永久代的字符串常量池中存储,返回也是永久代里面字符串实例引用。由 StringBuilder 创建的字符串对象实例在 java 堆上,所以必然不是同一个引用,结果返回 false。

jdk 7及以后的执行结果为

true
false

jdk 7中,intern() 实现就不需要 copy 字符串的实例到永久代了,既然字符串常量池已经移到 java 堆中,只需要在常量池里记录一下首次出现的实例引用即可,因此 intern() 返回的引用和 StringBuilder 创建的那个字符串实例就是同一个。

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

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

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

里做了讲解, 讲的很好。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值