Questions about Java's String pool

JavaStringString Pool

Java Problem Overview


Consider this code:

String first = "abc"; 
String second = new String("abc");

When using the new keyword, Java will create the abc String again right? Will this be stored on the regular heap or the String pool? How many Strings will end in the String pool?

Java Solutions


Solution 1 - Java

If you use the new keyword, a new String object will be created. Note that objects are always on the heap - the string pool is not a separate memory area that is separate from the heap.

The string pool is like a cache. If you do this:

String s = "abc";
String p = "abc";

then the Java compiler is smart enough to make just one String object, and s and p will both be referring to that same String object. If you do this:

String s = new String("abc");

then there will be one String object in the pool, the one that represents the literal "abc", and there will be a separate String object, not in the pool, that contains a copy of the content of the pooled object. Since String is immutable in Java, you're not gaining anything by doing this; calling new String("literal") never makes sense in Java and is unnecessarily inefficient.

Note that you can call intern() on a String object. This will put the String object in the pool if it is not already there, and return the reference to the pooled string. (If it was already in the pool, it just returns a reference to the object that was already there). See the API documentation for that method for more info.

See also String interning (Wikipedia).

Solution 2 - Java

In bytecode, the first assignment is:

Code:
0:   ldc     #2; //String abc
2:   astore_1

whereas the second is:

3:   new     #3; //class java/lang/String
6:   dup
7:   ldc     #2; //String abc
9:   invokespecial   #4; //Method java/lang/String."":(Ljava/lang/String;)V

So the first is in the pool (at position #2) whereas the second will be stored in the heap.

EDIT

Since the CONSTANT_String_info store the index as U2 (16 bits, unsigned) the pool can contain at max 2**16 = 65535 references. In the case you care here more limits of the JVM.

Solution 3 - Java

Each time your code create a string literal

for example:

String str="Hello"; (string literal) 

the JVM checks the string literal pool first. If the string already exists in the pool, a reference to the pooled instance returns. If the string does not exist in the pool, a new String object instantiates, then is placed in the pool. Java can make this optimization since strings are immutable and can be shared without fear of data corruption

Solution 4 - Java

String strObject = new String("Java");

and

String strLiteral = "Java";

Both expression gives you String object, but there is subtle difference between them. When you create String object using new() operator, it always create a new object in heap memory. On the other hand, if you create object using String literal syntax e.g. "Java", it may return an existing object from String pool (a cache of String object in Perm gen space, which is now moved to heap space in recent Java release), if it's already exists.

Solution 5 - Java

The only time you should use new String(foo) is when you want to break ==, which is an odd case, or when foo is a substring of a much larger string that has a limited lifetime, such as

String mystring;
{
   String source = getSomeHeinouslyLargeString();
   mystring = new String(source.substring(1,3));
}

Solution 6 - Java

Though late, may be useful for someone still come across this:

String first = "abc";
//One instance object in pool created. Instance variable “first” refers/points to pooled object

String second = new String("abc");    
//One instance object in heap created. Object in pool creation step will be skipped on account of first statement.

So in total 2 instance objects will be created. One in pool and other in heap

Detailed Explanation

> String first = "abc";

Here a string object with content "abc" created in pool. The instance variable “first” will point to pool object with content “abc”.

> String second = new String("abc");

Here another string object with content "abc" will be created in heap. The instance variable “second” will point to heap object with content “abc”. A string object with content "abc" creation in pool will be skipped on account of 1st statement. Reason below.

Reasons

If assumed prior statement (String first = "abc";) is not there with same content, then generally with “new” keyword, 2 string objects will be created one in heap (outside pool) and the other in pool(a subset area of heap). Also the instance variable "second" should point to heap object only, irrespective of whether the objects is in pool or not.

Now on account of the presence of prior statement (String first = "abc";) with same content as in new String("abc"), only one object (with content "abc") is retained in pool. So on account of 1st statement, the second statement will have only 1 object created instead of 2 and that object is in heap. Pool object creation will be skipped.

//Additional Test on the concept
System.out.println(first==second);  //returns false. Because first points to pool object while second points to heap object. And both objects are different (on account of different memory locations).

second = second.intern();   		//After interning, second now points to pool object. Note: intern is used so that reference variable points to pool area object and not heap object. Clearly it is applicable when we use new keyword.

System.out.println(first==second);  //returns true. Because now both first and second objects now points to same pool object.

Solution 7 - Java

String first = "abc"; 
String second = new String("abc");

In first case there is only one object will create in Pool. In second case two object will create one in pool (if this is not existing previously in Pool) and one in heap.

When you are passing any value with double quote ex: "abc" you are creating a object in pool and passing it to the string constructor for creating a new object with the same value in heap.

If you saw the string constructor you can see that it accept a string. What is that string? Before creation what is that string object. It's nothing but an object stored in String Constant pool.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionandandandandView Question on Stackoverflow
Solution 1 - JavaJesperView Answer on Stackoverflow
Solution 2 - JavadfaView Answer on Stackoverflow
Solution 3 - JavaloudiyimoView Answer on Stackoverflow
Solution 4 - JavavimalrajView Answer on Stackoverflow
Solution 5 - JavaMeBigFatGuyView Answer on Stackoverflow
Solution 6 - JavavinsinrawView Answer on Stackoverflow
Solution 7 - JavaKprasantaView Answer on Stackoverflow