The following codes has different results when run using JDK 8 and JDK 9.
public static void main(String[] args) {
String s = new String("1");
s.intern();
String s2 = "1";
System.out.println(s == s2);
String s3 = new String("1") + new String("1");
//String s3 = "1" + "1";
s3.intern();
String s4 = "11";
System.out.println(s3 == s4);
System.out.println(s3.equals(s4));
}
under JDK 8 (version 1.8.0_172), the codes prints:
false
true
true
but using JDK 9 (version 9.0.1),the codes returns:
false
false
true
I have checked two JDK versions and they are correct. Why does the code produce different results? Is there anything wrong with my program?
The result depends on whether the String "11" was already in the String pool prior to the call to s3.intern()
.
If it wasn't, s3.intern()
will add s3
to the pool and return s3
. In that case s4
will also be assigned the canonical representation of "11", since it was initialized with a String literal. Therefore s3==s4
would be true
.
If it was, s3.intern()
will return the canonical representation of "11", which is not the same instance as s3
. Therefore s3==s4
would be false
.
I don't have a JDK9 version to test your code on, but if that's the output you got, it implies that somewhere in the JDK9 source code that gets executed before your main
, there appears the "11" String
literal, which adds that String
to the pool.
This is not the case in JDK8.
Your test with the "1" String
gives false
in both cases, since the String
"1" is added to the pool when you pass it to the String
constructor in new String("1")
. Therefore s.intern()
doesn't add the String
referenced by s
to the pool, and String s2 = "1";
is a difference instance than s
.
The Javadoc of intern
is handy when trying to understand this behavior:
String java.lang.String.intern()
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.
...
All literal strings and string-valued constant expressions are interned.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With