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.