Jericho
Jericho

Reputation: 10953

Assign and create new String difference

String s1 = new String("string");
String s2 = new String("string");

String s3 = "string";
String s4 = "string";

System.out.println(s1 == s2);      //FALSE
System.out.println(s2.equals(s1)); //TRUE

System.out.println(s3 == s4);      //TRUE
System.out.println(s3.equals(s4)); //TRUE

What is the difference between creation of s1 and s3?

In String we are having only String object then why it treats this two differently. s1 and s2 are having different memory address while s3 and s4 has same memory address. Why it works based on new operator.?

Upvotes: 7

Views: 2147

Answers (4)

Stephen C
Stephen C

Reputation: 718836

The String objects that represent string literals in your Java source code are added to a shared String pool when the classes that defines them are loaded1. This ensures that all "copies" of a String literal are actually the same object ... even if the literal appears in multiple classes. That is why s3 == s4 is true.

By contrast, when you new a String, a distinct new String object is created. That is why s1 == s2 is false. (This is a fundamental property of new. It is guaranteed to create and return a new object ... if it completes normally.)

However, in either case, the strings will have the same characters, and that is why equals is returning true.


While it is important to understand what is going on, the real lesson is that the correct way to compare Java strings is to use equals and not ==.

If you want to arrange that your String objects can be tested for equality using ==, you can "intern" them using the String.intern method. However, you have to do this consistently ... and interning is an expensive process in various respects ... so it is generally not a good idea.


1 - Actually, it is a bit more complicated than that. They objects get added to the pool at some time between class loading and first use of the literals. The precise timing is unspecified and JVM implementation dependent. However it is guaranteed to happen just once, and before any application code sees the String object reference corresponding to the literal.

Upvotes: 9

Deepak Bala
Deepak Bala

Reputation: 11185

s1 is a new String object that does not belong to a part of any pooled instance. s3 is an instance of a string that comes from a pool. Lookup java String pool. Take a look at the related intern() method on String.

The concept is not unique to java. String interning is supported in other languages. On that related note, pooling frequently used objects follows the flyweight pattern and is not limited to Strings. Take a look at Integer.valueOf(). Integers have a constant pool of their own too.

Upvotes: 3

christopher
christopher

Reputation: 27346

The JVM has an automatic optimisation. Unless you specifically create a new String object, and another String object already exists with the same value, the JVM automatically assumes that a new object is not a necessity, and will assign you a pointer to the equal String object that already exists.

Essentially, when you use the second option, this is what happens:

Step 1

First Object is created no problem.

Step 2

Before the second object is created, the String pool is checked for a value. If that value currently exists, then there is no need to create a new object. It just returns the reference to the String object.

Step 3

Instead of being assigned a new Object, it is simply given a reference to the object made in step 1. This is to save memory.

Upvotes: 2

svz
svz

Reputation: 4588

This happens because the new operator forces creation of a new instance of String, while in the second case, as String is an immutable class, the JVM provides you with the same String instance for both variables to save memory. As there is no chance one of such objects will change causing the second one change as well (immutable, remember?) this is OK.

Upvotes: 0

Related Questions