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

这是一个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).toStri...

这是一个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());
    }
}

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

在Oracle JDK 1.7输出中是:

false
true

在OpenJDK 1.6输出中也是:

false
true

但在Oracle JDK 1.6输出中是:

false
false

正如此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?

输出:

true
true

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

false
false

结果是?

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

解决方法:

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

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

本文标题为:java – 为什么String.intern()在Oracle JDK 1.7中的行为有所不同?

基础教程推荐