为什么String.intern()在Oracle JDK 1.7中的行为有所不同?

arm*_*ong 5 java string

这是一个java片段:

public class TestIntern {
    public static void main(String[] argvs){
        String s1 = new StringBuilder("ja").append("va").toString();
        String s2 = new StringBuilder("go").append("lang").toString();
        System.out.println(s1 == s1.intern());
        System.out.println(s2 == s2.intern());
    }
}
Run Code Online (Sandbox Code Playgroud)

并且它根据不同的JDK表现不同

在Oracle JDK 1.7输出中是:

false
true
Run Code Online (Sandbox Code Playgroud)

在OpenJDK 1.6输出中也是:

false
true
Run Code Online (Sandbox Code Playgroud)

但在Oracle JDK 1.6输出中是:

false
false
Run Code Online (Sandbox Code Playgroud)

正如此String#intern方法的JavaDoc 所示

 * When the intern method is invoked, if the pool already contains a
 * string equal to this <code>String</code> object as determined by
 * the {@link #equals(Object)} method, then the string from the pool is
 * returned. Otherwise, this <code>String</code> object is added to the
 * pool and a reference to this <code>String</code> object is returned.
                           ~~~~
                             And what does *this* here mean? the string object
                             in the heap or in the string pool? if it returns 
                             object in the heap the out put should be:

                             true
                             true
                             otherwise should *always* be:

                             false
                             false
                             Am I right?
Run Code Online (Sandbox Code Playgroud)

输出:

true
true
Run Code Online (Sandbox Code Playgroud)

应该是预期的,但三个JDK都没有产生这个.以及为什么Oracle JDK1.6给出:

false
false
Run Code Online (Sandbox Code Playgroud)

结果是?

我认为在OracleJDK 1.7和openJDK 1.6 中,字符串池中必须有一些保留字符串,它们是什么?是否有文件指定所有保留的字符串?真的很困惑.

Ted*_*opp 5

是否s1.intern()返回s1或某个其他String对象取决于它在实习字符串池中找到的内容.如果String池中已有其他对象,intern()则返回该另一个对象; 否则它会将String引用的对象s1放入池中并返回相同的对象.

问题不在于不同的Java版本表现不同,而是在运行测试时,池碰巧包含不同的内容.我发现Oracle JDK 1.7和openJDK 1.6中的池恰好已包含字符串"java"但不包含字符串,这一点并不特别令人惊讶"golang".