大腿的博客

看深入理解java虚拟机记录-String.intern()

字数统计: 713阅读时长: 2 min
2019/03/13 Share

记录看深入理解java虚拟机关于String.inter()的信息。

历史

在看书之前,我记得在别的地方了解过intern()方法的内容。但是完全忘记了,在深入理解java虚拟机的方法区和运行时常量池溢出的小节时又看到了这个方法的引用。才慢慢想起自己以前了解过这个方法。在此记录。

intern()方法文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Returns a canonical representation for the string object. 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 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.
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.
---

返回字符串对象的规范表示。 最初为空的字符串池由String类私有维护。 调用实习方法时,如果池
已经包含等于此字符串对象的字符串(由equals(Object)方法确定),则返回池中的字符串。否
则,将此String对象添加到池中,并返回对此String对象的引用。 因此,对于任何两个字符串s和
t,当且仅当s.equals(t)为真时,s.intern()== t.intern()才为真。 所有文字字符串和
字符串值常量表达式都是实体。 字符串文字在The Java的3.10.5节中定义? 语言规范。

jdk版本变迁,运行时常量池的内存变迁导致的问题

代码

1
2
3
4
5
6
7
8
public class Main {
public static void main(String[] args) {
String s1 = new StringBuilder("ja").append("va").toString();
System.out.println(s1 == s1.intern());
String s2 = new StringBuilder("hello").append("word").toString();
System.out.println(s2 == s2.intern());
}
}

上面代码在jdk1.7以前会输出两个false。而在jdk1.7以后输出false和true。

原因

JDK1.6中,intern()方法会把首次遇到的字符串实例复制到永久代中,返回的也是永久代中这个字符串实例的引用,而由StringBuilder创建的字符串实例在java堆上,所以必然不是同一个引用,将返回false。
JDK1.7中的intern()实现不会再复制实例,只是在常量池中记录首次出现的的实例引用,因此intern()返回的引用和由StringBuilder创建的那个字符串实例是同一个。

未明白的问题

上面还有一个问题点在于对java字符串的比较,会返回false。书上的解释是

1
2
对“java”的比较返回的是false,是因为“java”这个字符串在执行StringBuilder.toString()
方法之前已经出现过,再进行比较时比较的就不是一个引用,所以false。

问题在于java字符串什么时候出现的?

CATALOG
  1. 1. 历史
  2. 2. intern()方法文档
  3. 3. jdk版本变迁,运行时常量池的内存变迁导致的问题
    1. 3.1. 代码
    2. 3.2. 原因
    3. 3.3. 未明白的问题