Reputation: 4848
I know that "==" compare reference and the a java String is immutable and use a string pool cache but I'm still confusing on this example :
final String fName = "James";
String lName = "Gosling";
String name1 = fName + lName;
String name2 = fName + "Gosling";
String name3 = "James" + "Gosling";
System.out.println(name1 == name2); // 1
System.out.println(name2 == name3);
This gave me as results :
false
true
I still confused why System.out.println(name1 == name2); give me a false as I know the both values should be cached in the string pool ?
Upvotes: 0
Views: 138
Reputation: 692231
Since fName
is final and initialized with a literal String, it's a constant expression.
So the instruction
String name2 = fName + "Gosling"
is compiled to
String name2 = "James" + "Gosling"
which is compiled to
String name2 = "JamesGosling"
So, in the bytecode, you have the equivalent of
String name2 = "JamesGosling";
String name3 = "JamesGosling";
So both name2 and name3 reference the same literal String, which is interned.
On the other hand, lName
is not final, and is thus not a constant expression, and the concatenation happens at runtime rather than at compile time. So the concatenation creates a new, non-interned String.
Upvotes: 3
Reputation: 14296
Creating two strings with same string values does not guarantee they are both from the String Pool. You need to call s.intern()
to ensure you get a String that has both same value and memory address from String Pool.
There is a good chance the concatenation is causing the String to be read as String Object instead of a String literal. This is due to the compiler not knowing if fName + lName
will result to a literal or not. If it's a String literal, it goes to the String Pool. If it's a String Object, it is is not guaranteed to go to the String Pool and be treated like any other Object.
Upvotes: 1