It seems that JDK7 process intern in a different way as before.
I tested it with build 1.7.0-b147 and got "both are equal", but when executing it (same bytecode) with 1,6.0_24 I do not get the message.
It also depends where the String b2 =...
line is located in the source code. The following code also does not output the message:
class Test {
public static void main(String... args) {
String s1 = "Good";
s1 = s1 + "morning";
String s2 = "Goodmorning";
System.out.println(s1.intern()); //just changed here s1.intern() and the if condition runs true
if(s1 == s2) {
System.out.println("both are equal");
} //now it works.
}
}
it seems like intern
after not finding the String in its pool of strings, inserts the actual instance s1 into the pool. The JVM is using that pool when s2 is created, so it gets the same reference as s1 back. On the other side, if s2 is created first, that reference is stored into the pool.
This can be a result of moving the interned Strings out from the permanent generation of the Java heap.
Found here: Important RFEs Addressed in JDK 7
In JDK 7, interned strings are no longer allocated in the permanent generation of the Java heap, but are instead allocated in the main part of the Java heap (known as the young and old generations), along with the other objects created by the application. This change will result in more data residing in the main Java heap, and less data in the permanent generation, and thus may require heap sizes to be adjusted. Most applications will see only relatively small differences in heap usage due to this change, but larger applications that load many classes or make heavy use of the String.intern() method will see more significant differences.
Not sure if that is a bug and from which version... The JLS 3.10.5 states
The result of explicitly interning a computed string is the same string as any pre-existing literal string with the same contents.
so the question is how pre-existing is interpreted, compile-time or execute-time: is "Goodmorning" pre-existing or not?
intern()
on the value of a local String variable (and not assigning the return value back to the local variable) magically make the variable's value compare equal to a literal??? – Onemans1 = s1.intern()
does the second snippet print out "both are equal". Are you sure the code is the same as what you have? – Valenciavalencienness1 = s1.intern()
or is itif (s1.intern() == s2)
? Just callingintern()
should not changes1
. – Waverleyboth are equal
in the second program. But when I run the same code using jdk6 I'm not gettingboth are equal
. So there must be some research efforts. – Casejdk6
hasif(s1==s2)
asfalse
but the same code injdk7
hasif(s1==s2)
astrue
why? – Case==
is the wrong way to test for String equality!" without even taking the time to understand the question. – Beene