As we know that when we create new String object by new keyword like this:
String str = new String("New String Will Have Two Objects");
It will create two objects of, one on java heap memory and other on String pool.
So when we call access "str" which string object is accessed(heap object or string pool object)?
According to my understanding the string pool object is get accessed, if yes then what happens to heap object?
If you are creating the String object with new
String str = new String("New String Will Have Two Objects");
In such case, JVM will create a new string object in normal(non pool) heap memory and the literal "New String Will Have Two Objects" will be placed in the string constant pool. The variable str will refer to the object in heap(non pool).
Method ‘intern()’ usage
This is best described by java docs
When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
String str = new String("New String Will Have Two Objects");
str.intern();
new String creates a new string on heap. This string's reference gets assigned to str.
String literals always have a reference to them from the String Literal Pool. That means that they always have a reference to them and are, therefore, not eligible for garbage collection http://www.javaranch.com/journal/200409/ScjpTipLine-StringsLiterally.html
Related
This question already has answers here:
What is the difference between "text" and new String("text")?
(13 answers)
Closed 6 years ago.
I read a lot about String Literal vs String Object. I read that String literal is stored in a String pool and String object will create an object in the heap. I'm quite confused in an instance variable of a class that is initialized using "".
class A {
private String aStr = "ASTRING";
}
Will aStr will be added to String pool or will it create an object in the heap?
Whenever new Keyword is used then object is created in heap.
Here new Keyword is not used so string object is created in string pool.
For example:
String s1= new String("string object");
In the above example two objects are being created one is string object in string pool since it is in double quotes another is s1 which is created in heap as new keyword is used.
As Gaur93 said its true, but i would like to add some more points.
Lets take an example:
String s = "hello";
String s1 = new String("hello");
String objects are basically wrappers around string literals. Unique string objects are pooled to prevent unnecessary object creation, and the JVM decide to pool string literals internally.
When you use a literal, say
String str = "hello"
the object in the pool is used. If you use String str = new String("hello"); , a new object is created, but the existing string literal may be reused on either the JVM level or bytecode level (at compile time).
You can check this by using .equals() method of java .
When a String is created using the keyword new it creates a new String object using a constructor that takes a String literal.
Does the literal get stored in the constant pool before the String constructor is called?
String hello = new String("Hello");
String literal = "Hello"; //Does "Hello" already exist in the pool
//or is it inserted at this line?
EDIT
In "OCA Java SE 7 Programmer I Certification Guide", Mala Gupta writes:
public static void main(String[] args)
{
String summer = new String("Summer"); // The code creates a new String object with the value "Summer". This object is not placed in the String constant pool.
String summer2 = "Summer" // The code creates a new String object with the value "Summer" and places it in the String constant pool.
}
She says on the first line that the String object that is created by new is not stored in the constant pool. This is fine, but what is not clear is if the literal "Summer" that goes in the constructor on the first line is.
On the second line she says that the assignment of "Summer" to summer2 stores it in the constant pool, which implies that the literal on the first line was not interned.
Regardless of where you are using, all string literals saves in String pool. So the answer is YES.
String hello = new String("Hello");
>--------< goes to pool.
But the thing is that the h2 won't refer from that h :)
When you write "Hello" in your code, this String is created during compilation.
so actually its already there since you also used it to create your new String("Hello");
with the "Hello" in it.
in conclusion: Yes.
String ob1 = new String("Hello");
String ob2 = "Hello";
First line first seeks a "Hello" string in String Pool, if it is there it creates same in Heap and our ob1 refers to that heap object. If it is not there it creates same in Pool also and in this case also, ob1 refers to heap object.
Second line also seeks for "Hello" object in pool if its found ob2 will refer to that pool object. If not found it will create only in Pool and ob2 will refer to that pool object.
But second line never creates an String object in heap. String objects kept in String Pool are reusable but String objects created in heap are not.
I know there are two ways of creating String in Java:
String a = "aaa";
String b = new String("bbb");
With the first way Java will definitely create a String object in the string pool and make a refer to it. (Assume "aaa" wan't in the pool before.)
With the second method, an object will be created in the heap, but will jvm also create an object in the string pool?
In this post Questions about Java's String pool, #Jesper said:
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.
If that's true, then every time with the new String("bbb");, a object "bbb" is created in the pool, which means by either way above, java will always create a string object in the pool. Then what is intern() used for ? In the docs http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#intern(), it says:
When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
That means there are cases that a string is not in the pool, is that possible ? Which one is true ?
As you know that String is an immutable object in Java programming language, which means once constructed can not be altered. Due to this, JVM has the ability to maintain a literal pool which is helpful to reduce the memory usage and to increase the performance. Each time when a String literal is used JVM checks the literal pool. If the literal is already available, the same reference would be returned. If the literal is not available, a new String object will be created and added in the literal pool.
This theory is applied when you try to create a String like a primitive or a literal/constant.
String str = "bbb";
But when you create a new String object
String str = new String("bbb");
the above mentioned rules are overridden and a new instance is created always.
But the intern API in the String class can be used to pick the String reference from the literal pool even though you create a String using new operator. Please check the below given example. Although the str3 is created using new operator since we used the intern method JVM picked up the reference from the literal pool.
public class StringInternExample {
public static void main(final String args[]) {
final String str = "bbb";
final String str1 = "bbb";
final String str2 = new String("bbb");
final String str3 = new String("bbb").intern();
System.out.println("str == str1 : "+(str == str1));
System.out.println("str == str2 : "+(str == str2));
System.out.println("str == str3 : "+(str == str3));
}
}
Output of above code:
str == str1 : true
str == str2 : false
str == str3 : true
You can have a look: Confusion on string immutability
Source of answer: http://ourownjava.com/java/java-string-immutability-and-intern-method/
Shishir
There are essentially two ways that our String objects can enter in to the pool:
Using a literal in source code like "bbb".
Using intern.
intern is for when you have a String that's not otherwise from the pool. For example:
String bb = "bbb".substring(1); // substring creates a new object
System.out.println(bb == "bb"); // false
System.out.println(bb.intern() == "bb"); // true
Or slightly different:
System.out.println(new String("bbb").intern() == "bbb"); // true
new String("bbb") does create two objects...
String fromLiteral = "bbb"; // in pool
String fromNewString = new String(fromLiteral); // not in pool
...but it's more like a special case. It creates two objects because "bbb" refers to an object:
A string literal is a reference to an instance of class String [...].
Moreover, a string literal always refers to the same instance of class String.
And new String(...) creates a copy of it.
However, there are many ways String objects are created without using a literal, such as:
All the String methods that perform some kind of mutation. (substring, split, replace, etc.)
Reading a String from some kind of input such as a Scanner or Reader.
Concatenation when at least one operand is not a compile-time constant.
intern lets you add them to the pool or retrieve an existing object if there was one. Under most circumstances interning Strings is unnecessary but it can be used as an optimization because:
It lets you compare with ==.
It can save memory because duplicates can be garbage collected.
Yes, new String("abc") will create a new object in memory, and thus it is advised to avoid it. Please have a look at item 5 of Josh Bloch's Effective Java, "Avoid creating unnecessary objects" where it is better explained:
As an extreme example of what not to do, consider this statement:
String s = new String("stringette"); // DON'T DO THIS!
The statement
creates a new String instance each time it is executed, and none of
those object creations is necessary. The argument to the String
constructor ("stringette") is itself a String instance, functionally
identical to all of the objects created by the constructor. If this
usage occurs in a loop or in a frequently invoked method, millions of
String instances can be created needlessly. The improved version is
simply the following:
String s = "stringette";
This version uses a
single String instance, rather than creating a new one each time it is
executed. Furthermore, it is guaranteed that the object will be reused
by any other code running in the same virtual machine that happens to
contain the same string literal [JLS, 3.10.5].
http://uet.vnu.edu.vn/~chauttm/e-books/java/Effective.Java.2nd.Edition.May.2008.3000th.Release.pdf
With the second method, an object will be created in the heap, but will jvm also create an object in the string pool?
Yes, but it is the string literal "bbb" which ensures the interned string1. The string constructor creates a new string object which is a copy with the same length and content - the newly created string is not automatically interned.
If that's true, then every time with the new String("bbb");, a object "bbb" is created in the pool, which means by either way above, java will always create a string object in the pool. Then what is intern() used for ?
Only string literals are automatically interned. Other string objects must be manually interned, if such is the desired behavior.
That means there are cases that a string is not in the pool, is that possible ?
With the exception of manual calls to String.intern, only string literals result in interned strings.
While I would recommend using a specialized collection for such cases, interning may be useful where it can be used to avoid creating extra duplicate objects. Some use-cases where interning can be beneficial - as in, the same string value can appear many times - is in JSON keys and XML element/attribute names.
1 This is trivial to reason, consider:
String _b = "bbb"; // string from string literal (this is interned)
String b = new String(_b); // create a NEW string via "copy constructor"
b == _b // -> false (new did NOT return an interned string)
b.equals(_b) // -> true (but it did return an equivalent string)
b.intern() == _b // -> true (which interns to .. the same string object)
Consider statement:
String s=new String("abc");
Will this statement creates two String objects namely "abc" and the one represented by 's'?
and if it creates two objects then will "abc" get stored in String pool or just discarded?
EDIT:
i am asking this question in reference to Difference between string object and string literal, where in the last two answers , creation of two objects is denied.
Avoid such kind of behavior , because "abc" is already a String and by making a new String, you are creating an unnecessary Object.
Instead go for String s = "abc";
This way, the String gets interned by the JVM and is added to a pool.
To answer your question, you are just creating an Object s that is referring to "abc".
So when you do say String t = new String("abc"); and then do s==t, will yield in false. Because they have their separate instances to abc.
String s = "HELLO";
Here "s" is a object reference variable of type String, which refers to the String literal object "Hello" which is added to the String Literal Pool.
String t = new String("Hello");
Here t is a object reference variable of type String, which refers to the String object "Hello" which is added to the String Pool.
Difference Between String Literal and String :
Assume
String s = "Hello";
String t = new String("Hello");
Now if following changes are done:
s = null;
t = null;
Hello String object associated with t will be a candidate for Garbage Collector, But Hello String Literal associated with s will NOT BE A CANDIDATE for Garbage Collector, as there will ALWAYS BE A REFERENCE FROM STRING LITERAL POOL to it.
I read in Kathy Sierra book that when we create String using new operator like String s = new String("abc") In this case, because we used the new keyword, Java will create a new String object in normal (nonpool) memory, and s will refer to it. In addition, literal "abc" will be placed in the pool.
intern() says that if String pool already contains a string then the string from the pool is returned Otherwise, the String object is added to the pool and a reference to this String object is returned.
If string "abc" when created using new also placed the string in the pool, then wht does intern() says that string from the pool is returned if String pool contains the string otherwise the string object is added to the pool.
Also I want to know if we create a String using new then actually how many objects get created?
TL;DR: If you ever really need to do new String("abc"), you'll know you need to and you'll know why. It's so rare that it's almost valid to say you never need to. Just use "abc".
The long version:
When you have the code new String("abc") the following things occur at various times:
When the class containing that code is loaded, if a string with the characters "abc" is not already in the intern pool, it's created and put there.
When the new String("abc") code is run:
A reference to the "abc" string from the intern pool is passed into the String constructor.
A new String object is created and initialized by copying the characters from the String passed into the constructor.
The new String object is returned to you.
If string "abc" when created using new also placed the string in the pool, then why does intern() says that string from the pool is returned if String pool contains the string otherwise the string object is added to the pool.
Because that's what intern does. Note that calling intern on a string literal is a no-op; string literals are all interned automatically. E.g.:
String s1 = "abc"; // Get a reference to the string defined by the literal
String s2 = s1.intern(); // No-op
System.out.println(s1 == s2); // "true"
System.out.println(s1 == "abc"); // "true", all literals are interned automatically
Also I want to know if we create a String using new then actually how many objects get created?
You create at least one String object (the new, non-interned one), and possibly two (if the literal wasn't already in the pool; but again, that bit happens earlier, when the class file's literals are loaded):
String s1 = "abc"; // Get a reference to the string defined by the literal
String s2 = new String(s1); // Create a new `String` object (guaranteed)
System.out.println(s1 == s2); // "false"
String s3 = s2.intern(); // Get the interned version of the string with these characters
System.out.println(s1 == s3); // "true"
String Pool is a pool of string references. Objects are created in Heap only.
When using new String("abc").intern() or using method like String s = "abc"; String pool is checked if there is an reference existing which refers to "abc".
In case reference for "abc" already exists in pool and .intern() is called on the reference referencing to an String object created using new String("abc"), then object created by new String("abc") is eligible for garbage collection. See below code for more clarity.
public static void main(String[] args) {
String s = new String("abc");
String a = s;
System.out.println(s==a);// true
String b = "abc";
s = s.intern();
System.out.println(s==a);// false
}