user2612619
user2612619

Reputation: 1129

Strings [= new String vs = ""]

So my question is in relation to declaring and assigning strings.

The way I usually declare strings is by doing the following:

String s1 = "Stackoverflow";

And then if I ever need to change the value of s1 I would do the following:

s1 = "new value";

Today I found another way of doing it and declaring a string would go like:

String s2 = new String("Stackoverflow");

And then changing the value would be:

s2 = new String("new value");

My question is what is the difference between the two or is it simply preferential. From looking at the code the fourth line

s2 = new String ("new value"); 

I'm assuming that doing that would create a new memory location and s2 would then point to it so I doubt it would be used to change the value but I can see it being used when declaring a string.

Upvotes: 1

Views: 1112

Answers (6)

Sage
Sage

Reputation: 15428

Creating String object Directly:

String s1 = "Hip Hop" 

will create a string object but first JVM checks the String constant or literal pool and if the string does not exist, it creates a new String object “Hip jop” and a reference is maintained in the pool. The variable s1 also refers the same object. Now, if we put a statement after this:

 String s2 = "Hip Hop"

JVM checks the String constant pool first and since the string already exists, a reference to the pooled instance is returned to s2.

System.out.println(s1==s2) // comparing reference and it will print true

java can make this optimization since strings are immutable and can be shared without fear of data corruption.

Creating String Object using new

String s3 = new String("Hip Hop")

For new keyword, a String object is created in the heap memory wither or not an equal string object already exists in the pool and s3 will refer to the newly created one.

System.out.println(s3==s2) // two reference is different, will print false 

String objects created with the new operator do not refer to objects in the string pool but can be made to using String’s intern() method. The java.lang.String.intern() returns an interned String, that is, one that has an entry in the global String literal pool. If the String is not already in the global String literal pool, then it will be added to the pool.

String s4 = s3.intern();
Systen.out.println(s4 == s2); // will print `true` because s4 is interned, 
               //it now have the same reference to "Hip Hop" as s2 or s1

But try:

Systen.out.println(s4 == s3) // it will be false,

As the reference of s4, s2 and s1 is the reference to the pooled instance while s3 is referring to the created object in heap memory.

use of new for creting string:

prior to OpenJDK 7, Update 6, Java String.susbtring method had potential memory leak. substring method would build a new String object keeping a reference to the whole char array, to avoid copying it. You could thus inadvertently keep a reference to a very big character array with just a one character string. If we want to have minimal strings after substring, we use the constructor taking another string :

String s2 = new String(s1.substring(0,1));

The issue is resolved in JDK 7 update 6. So No need to create string with new any more for taking advantage provided by String literal pool mechanism.

Referance:

  1. String literal pool
  2. using new to prevent memory leak for using substring

Upvotes: 0

Luckyman Nevermore
Luckyman Nevermore

Reputation: 61

enter image description here

@user2612619 here i want to say is .. when ever ur creating object with "new" operator it always falls in heap memory . so wenever u have same content but different objects than also it will create new objects on heap by this u cant save memory ....

but in order to save memory java people brought concept of immutable where we can save memory .. if u r creating a different object with same content .. string will recognize dat difference and creates only one object with same content and points the two references to only one object ..

i can solve ur doubts from this figure ..

case 1:

String s = new String("stackoverflow");
String s1 = new String("stackoverflow");

as they are two different objects on heap memory with two different values of hashcode .. so s==s1 (is reference comparison) it is false .. but s.equals(s1) is content comparison ..so it is true

case 2:

String s = "stackoverflow";
String s1 = "stackoverflow";

here objects fall in scp(string constant pool memory) same object for two different refernces .. so hashcode also same .. same reference value .. so s==s1 is true here [u can observe from figure clearly] s.equals(s1) is true as content comparison.. this is very beautiful concept .. u will love it wen u solve some problems ... all d best

Upvotes: 0

Loïc
Loïc

Reputation: 591

The main difference is that the constructor always creates a totally new instance of String containing the same characters than the original String.

String s1 = "Stackoverflow";
String s2 = "Stackoverflow";

Then s1 == s2 will return true

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

Then s1 == s2 will return false

Just using the double quotes option is often better:

  • With a constructors you might create two instance of String.
  • Easier to read and less confusing

Upvotes: 0

ASD
ASD

Reputation: 41

String s1 = "Stackoverflow";

This line will create a new object in the String pool if it does not exist already. That means first it will first try searching for "Stackoverflow" in the String pool, if found then s1 will start pointing to it, if not found then it will create a new object and s1 will refer to it.

String s2 = new String("Stackoverflow");

Will always create a new String object, no matter if the value already exists in the String pool. So the object in the heap would then have the value "Stackovrflow" and s2 will start pointing to it.

s2 = new String("new value");

This will again create a new Object and s2 will start pointing to it. The earlier object that s2 was pointing to is not open for garbage collection (gc).

Let me know if this helps.

Upvotes: 0

Umer Farooq
Umer Farooq

Reputation: 7486

String s1 = "Stackoverflow"; // declaring & initializing s1

String s2 = new String("Stackoverflow"); // declaring & initializing s2

in above cases you are declaring & initializing String object.

The difference between

//first case

String s2 = new String("new String"); // declaring & initializing s2 with new memory

// second case

s2 = "new String" // overwriting previous value of s2

is in the first case you are creating a new object, i-e; allocating memory for a new object which will be refrenced by s2. The previous address to which s2 was pointing/referencing hasn't released the memory yet which will be gc when the program ends or when system needs to.

The good programming practice (second case) is to initialize an object once, and if you want to change its value either assign null to it and then allocate new memory to it or in case of string you can do like this

s2= "new String";

Upvotes: 0

Denys Séguret
Denys Séguret

Reputation: 382464

From the javadoc :

Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since Strings are immutable.

So no, you have no reason not to use the simple literal.

Simply do

String s1 = "Stackoverflow";

Historically, this constructor was mainly used to get a lighter copy of a string obtained by splitting a bigger one (see this question). Now, There's no normal reason to use it.

Upvotes: 6

Related Questions