Saurabh Agarwal
Saurabh Agarwal

Reputation: 323

How many String object..?

Me and my friend was discussing on Strings and we stuck on this:

String str = "ObjectOne"+"ObjectTwo";

He says total three Object will be created and I say one object will be created.

His logic behind 3 objects is: one for "ObjectOne" and one for "ObjectTwo" and third one is the concatenated version of two String objects.

My logic behind one object is at compile time both the string objects will be concatenated in the byte code as:

String str = "ObjectOneObjectTwo";  

And at run time only one object will be created in such a way. What is the truth behind this.

Upvotes: 6

Views: 680

Answers (6)

Raghunandan
Raghunandan

Reputation: 133560

String object is immutable.

    String str = "ObjectOne"+"ObjectTwo"; 

         is same as

    String str = "ObjectOneObjectTwo"; 

By immutable, we mean that the value stored in the String object cannot be changed. Then the next question that comes to our mind is “If String is immutable then how am I able to change the contents of the object whenever I wish to?” . Well, to be precise it’s not the same String object that reflects the changes you do. Internally a new String object is created to do the changes.

So suppose you declare a String object:

 String myString = "Hello";

Next, you want to append “Guest” to the same String. What do you do?

myString = myString + " Guest";

When you print the contents of myString the output will be “Hello Guest”. Although we made use of the same object(myString), internally a new object was created in the process. So mystring will be refering to "Hello Guest". Reference to hello is lost.

  String s1 = "hello"; //case 1 
  String s2 = "hello"; //case 2 

In case 1, literal s1 is created newly and kept in the pool. But in case 2, literal s2 refer the s1, it will not create new one instead.

if(s1 == s2) System.out.println("equal"); //Prints equal

      String s= "abc"; //initaly s refers to abc
      String s2 =s;    //s2 also refers to abc
      s=s.concat("def"); // s refers to abcdef. s no longer refers to abc.

enter image description here

Upvotes: 0

AmitG
AmitG

Reputation: 10543

String str1 = "ObjectOne";
String str2 = "ObjectTwo";
str1 = str1+str2;

In above case three objects will be created.

But when you define like

String str = "ObjectOne"+"ObjectTwo";

then only one object will be created. Compiler optimizes it.

Upvotes: 0

Simon Dorociak
Simon Dorociak

Reputation: 33505

If you write(literals or constants)

String str = "ObjectOne"+"ObjectTwo";

it's equivalent to

String str = "ObjectOneObjectTwo"; // compiler optimize it so one Object

Upvotes: 11

meriton
meriton

Reputation: 70564

You can easily check this yourself:

  1. Compile the following program:

    public static void main(String[] args) {
        String str = "ObjectOne"+"ObjectTwo";
        System.out.println(str);
    }
    
  2. Inspect the bytecode emitted by the compiler:

    javap.exe -v Test.class
    

For the main method, this prints:

  public static void main(java.lang.String[]);
    flags: ACC_PUBLIC, ACC_STATIC

    Code:
      stack=2, locals=2, args_size=1
         0: ldc           #16                 // String ObjectOneObjectTwo
         2: astore_1      
         3: getstatic     #18                 // Field java/lang/System.out:Ljava/io/PrintStream;
         6: aload_1       
         7: invokevirtual #24                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        10: return        
      LineNumberTable:
        line 6: 0
        line 7: 3
        line 8: 10
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      11     0  args   [Ljava/lang/String;
               3       8     1   str   Ljava/lang/String;
}

As you can see, the programm uses the ldc bytecode instruction to refer to a single, already loaded string instance (which is loaded when Test.class is). No new object is therefore created during execution of that line.

The compiler is required to perform this optimization by the Java Language Specification :

The String object is newly created (§12.5) unless the expression is a compile-time constant expression (§15.28).

Upvotes: 1

Nirbhay Mishra
Nirbhay Mishra

Reputation: 1648

String str = "ObjectOne"+"ObjectTwo";

3 objects will be created as

1- "ObjectOne"

2- "ObjectTwo"

3- "ObjectOneObjectTwo"

use

StringBuffer tmp = new StringBuffer("ObjectOne");
tmp.append("ObjectTwo");
str = tmp.toString();

Upvotes: -3

Jesper
Jesper

Reputation: 206806

You can find this out for yourself by using the javap tool to disassemble the code, to see what the compiler made of it. Suppose you have this example:

public class Example {
    public static void main(String[] args) {
        String s = "ObjectOne" + "ObjectTwo";
        System.out.println(s);
    }
}

Compile it, then disassemble it with javap -c Example. The result is:

Compiled from "Example.java"
public class Example {
  public Example();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: ldc           #2                  // String ObjectOneObjectTwo
       2: astore_1
       3: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
       6: aload_1
       7: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      10: return
}

As you see, there is only one String object, which contains "ObjectOneObjectTwo". So, indeed, the compiler does the concatenation for you at compile time.

Upvotes: 7

Related Questions