这是一个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 中,字符串池中必须有一些保留字符串,它们是什么?是否有文件指定所有保留的字符串?真的很困惑.
是否s1.intern()
返回s1
或某个其他String
对象取决于它在实习字符串池中找到的内容.如果String
池中已有其他对象,intern()
则返回该另一个对象; 否则它会将String
引用的对象s1
放入池中并返回相同的对象.
问题不在于不同的Java版本表现不同,而是在运行测试时,池碰巧包含不同的内容.我发现Oracle JDK 1.7和openJDK 1.6中的池恰好已包含字符串"java"
但不包含字符串,这一点并不特别令人惊讶"golang"
.