4

Visit String Constant Pool Java !

public class StringLiterals {
    public static void main(String[] args) {
        String s1="This is ";
        s1=s1+"my book";
        String s2="This is my book";
        System.out.println(s1==s2);

    }
}

O/P:False

Expecting O/P:True

Community
  • 1
  • 1
Barnwal Vivek
  • 171
  • 2
  • 11

5 Answers5

6

Maybe this will help clear things up.

    String s1 = "This is";
    s1 = s1 + " my book"; // Note the space
    String s2 = "This is my book";
    String s3 = "This is my book";
    System.out.println(s1==s2); // False
    System.out.println(s2==s3); // True

"Strings are only put in the pool when they are interned explicitly or by the class's use of a literal." Hence, you cannot concatenate strings with the + operator and expect it to be put into the string constant pool.

Kent Shikama
  • 3,910
  • 3
  • 22
  • 55
3

Your code compiles into

  public static void main(java.lang.String[]);
    Code:
       0: ldc           #16                 // String This is 
       2: astore_1      
       3: new           #18                 // class java/lang/StringBuilder
       6: dup           
       7: aload_1       
       8: invokestatic  #20                 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
      11: invokespecial #26                 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
      14: ldc           #29                 // String my book
      16: invokevirtual #31                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      19: invokevirtual #35                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      22: astore_1      
      23: ldc           #39                 // String This is my book
      25: astore_2      
      26: getstatic     #41                 // Field java/lang/System.out:Ljava/io/PrintStream;
      29: aload_1       
      30: aload_2       
      31: if_acmpne     38
      34: iconst_1      
      35: goto          39
      38: iconst_0      
      39: invokevirtual #47                 // Method java/io/PrintStream.println:(Z)V
      42: return   

which is equivalent to

public static void main(String[] args) {
    StringBuilder sb = new StringBuilder("This is ");
    sb.append("my book");
    String s1 = sb.toString();
    String s2 = "This is my book";
    System.out.println(s1 == s2);
}

because

s1=s1+"my book";

is not a constant expression - you are reading the value of a variable and the compiler will assume that you could have changed it in the meantime. If you want that

Strings computed by constant expressions (§15.28) are computed at compile time and then treated as if they were literals. JLS (§3.10.5)

applies you would have to change your code to

public static void main(String[] args) {
    String s1 = "This is " + "my book";
    String s2 = "This is my book";
    System.out.println(s1 == s2);
}

or

public static void main(String[] args) {
    final String s1a = "This is ";
    final String s1b = "my book";
    String s1 = s1a + s1b;

    String s2 = "This is my book";
    System.out.println(s1 == s2);
}

and now you are guaranteed that it works. Second example compiles to

  public static void main(java.lang.String[]);
    Code:
       0: ldc           #16                 // String This is 
       2: astore_1      
       3: ldc           #18                 // String my book
       5: astore_2      
       6: ldc           #20                 // String This is my book
       8: astore_3      
       9: ldc           #20                 // String This is my book
      11: astore        4
      13: getstatic     #22                 // Field java/lang/System.out:Ljava/io/PrintStream;
      16: aload_3       
      17: aload         4
      19: if_acmpne     26
      22: iconst_1      
      23: goto          27
      26: iconst_0      
      27: invokevirtual #28                 // Method java/io/PrintStream.println:(Z)V
      30: return    

and as you can see loads 2 times String #20

zapl
  • 63,179
  • 10
  • 123
  • 154
2

Firstly, you are missing a space. I assume that's just a mistake.

You have probably seen something like this:

"This is"+" my book" == "This is my book"

Why does that work? Because it's all compile-time constants JLS 7 15.28. In particular "literals of type String" and "The additive operators + and -".

There's also "Simple names [...] that refer to constant variables". But this doesn't apply as your variable is not final.

But it's not something you should particularly need to know about. Just use equals for Strings.

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
0

You cannot use == to compare two Strings, as the == operator is asserting that s1 and s2 point to the same memory location, and not that the contents are equal. To compare the contents of two Strings to see if they contain the same content, use String's .equals() method. Plus you needed an extra space on the s1=s1+ line.

Code:

{
public class StringLiterals {
public static void main(String[] args) {
    String s1="This is";
    s1=s1+" my book";
    String s2="This is my book";
    System.out.println(s1.equals(s2));

    }
}

If you want to use ==, you will then have to use this:

public class StringLiterals
{
  public static void main(String[] args)
  {
    String s1 = "This is my book";
    String s2 = s1;
    System.out.println(s1 == s2);
  }
}

Because Strings are objects, their == act differently than ints, chars, and other primitives.

Mike Koch
  • 1,540
  • 2
  • 17
  • 23
-1

The presence of + operator results in new String. Here s1 = s1 + " my book", s1+ " my book " implicitly creates new String and store its reference to s1. So it is different from s2

Mohan Raj B
  • 1,015
  • 7
  • 14