I've read this answer about how to check if a string is interned in Java, but I don't understand the following results:
String x = args[0]; // args[0] = "abc";
String a = "a";
String y = a + "bc";
System.out.println(y.intern() == y); // true
But if I declare a string literal:
String x = "abc";
String a = "a";
String y = a + "bc";
System.out.println(y.intern() == y); // false
Besides, without any string literal, the args[0]
seems to be directly interned:
// String x = "abc";
String y = args[0];
System.out.println(y.intern() == y); // true (???)
// false if the first line is uncommented
Why does y.intern() == y
change depending on whether x
is a literal or not, even for the example when the command-line argument is used?
I know literal strings are interned at compile time, but I don't get why it affects in the previous examples. I have also read several questions about string interning, like String Pool behavior, Questions about Java's String pool and Java String pool - When does the pool change?. However, none of them gives a possible explanation to this behaviour.
Edit:
I wrongly wrote that in third example the result doesn't change if String x = "abc";
is declared, but it does.
It is because y.intern()
gives back y
if the string was not interned before. If the string already existed, the call will give back the already existing instance which is most likely different from y
.
However, all this is highly implementation dependent so may be different on different versions of the JVM and the compiler.