Me and my friend was discussing on Strings and we stuck on this:
String str = \"ObjectOne\"+\"ObjectTwo\";
He says total three Object will
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.
You can easily check this yourself:
Compile the following program:
public static void main(String[] args) {
String str = "ObjectOne"+"ObjectTwo";
System.out.println(str);
}
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).
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();
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.
If you write(literals or constants)
String str = "ObjectOne"+"ObjectTwo";
it's equivalent to
String str = "ObjectOneObjectTwo"; // compiler optimize it so one Object
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.