I recently went back to the String comparisons in Java and tried this:
String s = "hello"; System.out.println(s == "hello"); System.out.println(s.equals("hello"));
When I run it with jdk 19.0.1, Both expressions evaluate to
true despite IDE warnings.
This is obviously against all my intuition, as I’ve been told since my very first day programming in Java that the first expression should be evaluate to
false because they are different objects. My best guess is that Java has done some optimization at some point to override String comparison with
==, only I would like to know when did they do that.
Does anyone remember in which Java version has this optimization been done? Thanks.
You are correct that
== operator in Java will only return
true if both references are pointing to the exact same object.
Now for why does
s == "hello" return
true for your example it has to do with how the Java compiler works.
In Java all strings are immutable. This means the objects themselves can not be changed. When you update the contents of a string in Java a new string object is created.
This allows the Java compiler to save memory at runtime by implementing string interning. Any string that is defined in the source code as a literal is placed in a string intern pool. When adding a string literal to this pool the complier checks if that string is in the pool and if yes returns a reference to the existing string. This means if you use the same string literal multiple times in the source code it is only stored once in memory.
In your example you use the string literal
"hello" three times. When compiled all 3 string literals become the same string object. This is why in your example
s == "hello" returns
== is bad practice when comparing strings in Java. It happens to "work" in your example because of how your example code is written and how the Java compiler works.