5

I'm trying to understand reference comparing in Java. Let's assume we have the following main code:

public static void main (String args[]) {
   String str1 = "Love!";  
   String str2 = "Love!";
   String str3 = new String("Love!");  
   String str4 = new String("Love!");
   String str5 = "Lov"+ "e!";  
   String str6 = "Lo" + "ve!";  
   String s = "e!";
   String str7 = "Lov"+ s;  
   String str8 = "Lo" + "ve!";
   String str9 = str1;
}

I understand that str1 == str2 == str5 == str6 == str8 == str9 and all of them are the same reference to the common pool. (value "Love!"). s is a reference to the common pool as well, but it refers the value "e!"

I understand also that str1 != s.

I know that str3, str4 are references to the HEAP, and each of them is a different Object. str3 != str4.

I do NOT understand why str1 != str7, and I would love to get an explanation.

trincot
  • 317,000
  • 35
  • 244
  • 286
DifferentPulses
  • 404
  • 2
  • 17
  • 1
    If you "understand" that `str1 == str4`, then you need to forget what you think you know, because it is not. `str3`, `str4`, and `str7` are all 3 independent objects. – Andreas Jul 23 '17 at 21:10
  • yes my bad. it's in the heap. str3, str4 in the heap. sorry – DifferentPulses Jul 23 '17 at 21:13
  • 1
    Simple answer: the compiler treats it specially when you concatenate two strings and the compiler knows what those strings are (because they're string literals or `static final` constants). `s` is a variable, which is why `str7` doesn't fall into that case. – ajb Jul 23 '17 at 21:13
  • 3
    String concatenation of *literals* and/or *compile-time constants* are applied by the compiler, so the concatenated result is added to the string pool. Concatenation involving non-constant variables will always create a new string. Since `s` is not a constant, `str7` is a new string. – Andreas Jul 23 '17 at 21:13
  • ajb, could you elaborate please? – DifferentPulses Jul 23 '17 at 21:14
  • @Andreas I win by 18 seconds. But I think last time we both posted virtually identical comments, you won by 30 seconds, so I guess you're still ahead by a little bit. – ajb Jul 23 '17 at 21:16
  • @Andreas don't be mad at me about str4, it was a typo. – DifferentPulses Jul 23 '17 at 21:18
  • 1
    Related: [Comparing strings with == which are declared final in Java](https://stackoverflow.com/questions/19418427/comparing-strings-with-which-are-declared-final-in-java) – Pshemo Jul 23 '17 at 21:22

1 Answers1

14

In

String s = "e!";
String str7 = "Lov"+ s;

While "e!" is a constant expression, s is not a constant variable (JLS §4.12.4); therefore, "Lov" + s, which references s, cannot be a constant expression (JLS §15.28). In order for a variable like s to be a constant variable, it needs to be both final and initialized from a constant expression.

If you had written

final String s = "e!";
String str7 = "Lov" + s;

then str1 == str7 would have been true.

HTNW
  • 27,182
  • 1
  • 32
  • 60