You have stumbled across the intricacies of how the Java compiler optimizes String.
Suppose I have this program:
String a = "abc";
String b = "abc";
Here the compiler can initialize a and b to the same String instance. This entails that a == b and a.equals(b).
Here we also get the same behaviour:
String a = "abc";
String b = "ab" + "c";
This is because "ab" + "c" can be evaluated at compile-time to just "abc", which in turn can share an instance with a.
This technique is not possible with expressions that call functions:
String a = "abc";
String b = "ab" + functionThatReturnsC();
This is because functionThatReturnsC could have side-effects which cannot be resolved at compile-time.
Your case of returnVal is interesting. Since it is constant, it could be inlined, in which case the compile-time instance sharing could be applied. It seems the compiler implementer decided not to support this.
This issue exposes a weakness of Java. Since we cannot override =, programmers cannot implement custom value-types. Therefore, you should always use equals or Objects.equals to ensure consistent behaviour.
Note that these optimizations may differ between compilers.