There are quite a lot of answers here which exlain that, but let me give you another one.
A string is interned into the String literal pool only in two situations: when a class is loaded and the String was a literal or compile time constant. Otherwise only when you call .intern()
on a String. Then a copy of this string is listed in the pool and returned. All other string creations will not be interned. String concatenation (+
) is producing new instances as long as it is not a compile time constant expression*.
First of all: never ever use it. If you do not understand it you should not use it. Use .equals()
. Interning strings for the sake of comparison might be slower than you think and unnecessarily filling the hashtable. Especially for strings with highly different content.
- s3 is a string literal from the constant pool and therefore interned. s4 is a expression not producing an interned constant.
- when you intern s4 it has the same content as s3 and is therefore the same instance.
- same as s4, expression not a constant
- if you intern s1+s2 you get the instance of s3, but s4 is still not s3
- if you intern s4 it is the same instance as s3
Some more questions:
System.out.println(s3 == s3.intern()); // is true
System.out.println(s4 == s4.intern()); // is false
System.out.println(s1 == "abc"); // is true
System.out.println(s1 == new String("abc")); // is false
* Compile time constants can be expressions with literals on both sides of the concatenation (like "a" + "bc"
) but also final String variables initialized from constants or literals:
final String a = "a";
final String b = "b";
final String ab = a + b;
final String ab2 = "a" + b;
final String ab3 = "a" + new String("b");
System.out.println("ab == ab2 should be true: " + (ab == ab2));
System.out.println("a+b == ab should be true: " + (a+b == ab));
System.out.println("ab == ab3 should be false: " + (ab == ab3));