-1

I have this code which I cannot understand. In the beginning you can see two identical Strings, and when I compare them with use of operator == it says it is true, same as equals() method, but when I create two identical strings during runtime operator == says false. Why is this happening ?

Does it mean that when I hardcode identical strings they are placed in the same position in the memory and both references point to it? I found similar question, but there were no explicit answer.

public class StringTesting {
    public static void main(String[] args){
        String string1 = "hello";                   //\
                                                    // } same place in the memory ?
        String string2 = "hello";                   ///

        System.out.println(string1 == string2);     //true
        System.out.println(string1.equals(string2));      //true

        String string3 = "hey";
        String string4 = "he";

        System.out.println(string3 == string4);          //false
        System.out.println(string3.equals(string4));     //false

        string4 += "y";

        System.out.println(string3 == string4);          //false ????
        System.out.println(string3.equals(string4));     //true

        System.out.println(string3 + " " + string4);      //hey hey
    }
}
Community
  • 1
  • 1
ashur
  • 4,177
  • 14
  • 53
  • 85

3 Answers3

4

The following compound assignment operator:

string4 += "y";

performs String concatenation at runtime. Since the value of string4 is evaluated at runtime only. And String concatenation done at runtime creates a new object.

From JLS Section 3.10.5 (See towards the end of this section):

Strings computed by concatenation at run time are newly created and therefore distinct.

However if you perform concatenation of two string literals, it won't create a different objects. So the following code will return true:

"he" + "y" == "hey";

That JLS section contains code segment for various string concatenation example:

String hello = "Hello", 
String lo = "lo";

System.out.print((hello == "Hello") + " ");          // true
System.out.print((Other.hello == hello) + " ");      // true
System.out.print((other.Other.hello == hello) + " ");// true
System.out.print((hello == ("Hel" + "lo")) + " ");     // true
System.out.print((hello == ("Hel" + lo)) + " ");       // false
System.out.println(hello == ("Hel" + lo).intern());    // true
Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • Also, with `public static final String he0 = "he"; public static String he1 = "he";`, `he0 + "y" == "hey" && he1 + "y" != "hey"` and this is true even if he0 is moved into a different compilation unit. – Mike Samuel Aug 23 '13 at 22:32
  • @MikeSamuel. Of course. Thanks for pointing that out. Missed it in my answer. :) – Rohit Jain Aug 23 '13 at 22:35
0

string4 += "y"; creates a new object.

String literals however are placed in the same place in memory as an optimization (this is called string interning).

tskuzzy
  • 35,812
  • 14
  • 73
  • 140
0

string1, string2, and string3 are all string constants. i.e., they appear as constant pool entries in the .class file. In Java, string constants are interned.

string4 is a new string, created by taking the string constant "he" and then appending "y". Therefore, it's not a string constant, and is not interned.

That is why string3 != string4.

C. K. Young
  • 219,335
  • 46
  • 382
  • 435