This question already has answers here:
Number of objects created when using String intern method in Java
(3 answers)
Closed 4 years ago.
I understanding the internal working of intern() in java. It will start referring to the string pool area object. But when we use inter() along with new, does it still create an object in heap and the reference is now pointing to pool object? Or is it that it wouldn't create any heap object at all?
String s1 = new String("hello").intern();
For example in the above line, when intern is used, is it creating only one object in the string pool and referring it? Or is it creating one object in heap and one object in pool and it starts referring to pool object, thereby leaving the object at heap for garbage collection?
In the Oracle/OpenJDK it doesn't create any objects, however, this is implementation dependent.
The method intern() either returns the existing object, in this case, the original "Hi" or the String used to call intern
But when we use inter() along with new, does it still create an object in heap and the reference is now pointing to pool object?
String literals are still in the heap. Nothing is moved to add it to this pool
For example in the above line, when intern is used, is it creating only one object in the string pool and referring it?
This is only creating one object, wrapping the char[] or byte[] of the original String literal. The intern will return the original string literal.
Or is it creating one object in heap and one object in pool and it starts referring to pool object, thereby leaving the object at heap for garbage collection?
The string literal pool is implemented in native memory and is not made up of objects.
For comparison, this call to intern() adds the new string to the literal pool as concat is computed at runtime.
String hi = "h".concat("i").intern();
This does nothing as the + is computed at compile time.
String hi = ("h" + "i").intern();
If you look at the documentation this quote here explains exactly what happens.
https://docs.oracle.com/javase/9/docs/api/java/lang/String.html#intern--
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.
So with your question:
For example in the above line, when intern is used, is it creating only one object in the string pool and referring it? Or is it creating one object in heap and one object in pool and it starts referring to pool object, thereby leaving the object at heap for garbage collection?
bold faced is what is happening.
Here you can see in this demonstration that your code returns the interned object.
https://ideone.com/dKFkEl
String s1 = new String("hello").intern();
String s2 = new String("hello");
String s3 = "hello";
System.out.println("s1 == s2 = "+(s1 == s2));// false
System.out.println("s1 == s3 = "+(s1 == s3));// true
System.out.println("s2 == s3 = "+(s2 == s3));// false
Related
This question already has answers here:
Questions about Java's String pool [duplicate]
(7 answers)
Closed 4 years ago.
Say if there are no strings in the String constant pool, and if I say,
String s = "Java";
Then how many objects will be created?
Now again nothing in the pool, and I say,
String s = new String("Java");
Now, how many objects will be created?
Now again nothing in the pool, and I say,
String s = new String("Java");
s.intern();
What will the intern method do?
Now again nothing in the pool, and I say,
String s = new String("Java");
String s1 = s.intern();
What will happen now?
Please answer as I am really confused about it.
As I read in SCJP5 Kathy Sierra book, that when you create a String with new, then 2 objects are created, one on the heap and one in the pool.
I will assume that in each example below you load and execute the code exactly once, in a new JVM each time. (I will also assume that nowhere else in your code do you use the literal "Java" ... since that would complicate things.)
1) Say if there are no strings in the String constant pool, and if i
say,
String s = "Java";
Then how many objects will be created ?
One string is created and added to the pool when method is loaded.
2) Now again nothing in the pool, and i say,
String s = new String("Java");
Now how many objects will be created.
One string is created and added to the pool when method is loaded.
A second string is created by the new when the code is run, and it is NOT added to the pool.
3) Now again nothing in the pool, and i say,
String s = new String("Java");
s.intern();
What will the intern method do ?
One string is created and added to the pool when method is loaded.
A second string is created by the new, and it is NOT added to the pool.
The intern call returns the first string. (You don't keep the reference ...)
4) Now again nothing in the pool, and i say,
String s = new String("Java");
String s1 = s.intern();
What will happen now?
Same as example 3. Thus, s1 will hold a reference to the String object that represents the "Java" string literal.
I read in SCJP5 Kathy Sierra book, that when you create a String with new, then 2 objects are created, one on the heap and one in the pool.
I doubt that the book said that exactly. (You are paraphrasing, and I think you have paraphrased somewhat inaccurately.)
However, your paraphrasing is roughly correct, though (an this is important!) the string object representing the literal is created and added to the pool when the code fragment is loaded1, not when it is executed.
And to address another point of confusion:
"What i actually meant was that from the answer that you gave, it seems that a String will always be added in the String constant pool."
That is incorrect. It is a false generalization.
While it is true for all 4 of the cases above, it will not be true for others. It depends on where the original string came from. In typical applications, most text data is read from a file, socket, or a user interface. When that happens, the strings are created from arrays of characters, either directly or via a library call.
Here is a simple (but unrealistic) example that shows creating a String from its component characters.
String s = new String(new char[]{'J', 'a', 'v', 'a'});
In the snippet above, only one String is created, and it is NOT in the String pool. If you wanted the resulting string to be in the string pool you need to explicitly call intern something like this:
String s = new String(new char[]{'J', 'a', 'v', 'a'});
s = s.intern();
... which will (if necessary) create a second string in the string pool2.
1 - Apparently, in some JVMs creation and interning string literals is done lazily, so it is not possible to say with 100% certainty when it actually happens. However, it will only occur once (per class that references the literal), no matter how many times the code fragment is executed by the JVM.
2 - There is no way to new a string into the string pool. It would actually be a violation of the JLS. The new operation is specified by the JLS as always creating a new object.
Then how many objects will be created?
There is one String in the pool.
Now how many objects will be created?
One String will be created, there is still one String in the pool.
What will the intern method do?
It will try to put a "Java" into the pool, find another "Java" there, are return a reference to that "Java" from step 1.
What will happen now?
The "Java" from step 1 will come back and s1 now refers to it.
Say if there are no strings in the String constant pool, and if i say,
String s = "Java";
Then how many objects will be created ?
One String object is created in intern pool.
s is assigned by that reference.
Now again nothing in the pool, and i say,
String s = new String("Java");
Now how many objects will be created.
Two String object is created.
One is interned "Java", and one is new String with the same content of "Java"
Now again nothing in the pool, and i say,
String s = new String("Java");
s.intern();
What will the intern method do ?
The intern() method will:
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.
So in this case, this String is added to the pool and a reference to this is returned
And the last question:
Now again nothing in the pool, and i say,
String s = new String("Java");
String s1 = s.intern();
What will happen now?
What happen here is:
String "Java" is added to the pool
New String is created, backed by the same char[] array "Java"
s.intern() look for a reference in the pool and s1 is assigned by the interned reference
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. Otherwise it will create a new string object and put in string pool for future re-use.
String s = "Java";
One object will be created in Pool.
Now again nothing in the pool, and i say,
String s = new String("Java");
One Object will be created in Heap
Now again nothing in the pool, and i say,
String s = new String("Java");
s.intern();
What will the intern method do ?
intern() method will copy the Sting object into pool, but it will be no use, as it is not referenced, hence there will be only object in Heap
Now again nothing in the pool, and i say,
String s = new String("Java");
String s1 = s.intern();
What will happen now?
one object in Heap and one object in Pool will be created.
I have seen many questions regarding object created using string literal and new keyword like:
How many String objects using new operator
But it doesn't clarify my doubts.
Case 1: String object using string literal.
It creates one object in string constant pool if,it is not present otherwise, return the reference of this object.This object is implicitly interned.
Case 2:String object using new().
it creates 2 objects,one in string constant pool and another one in heap area.Reference variable refer to the heap area object.For this object we need to call intern method to put this object into string constant pool explicitly.
My question is if new() already creates one object in string constant pool then, what is use of calling intern method on the object which is there in heap area?
Case 2:String object using new(). it creates 2 objects,one in string constant pool and another one in heap area.
Only if you create a new String object by passing it a string literal, like this:
String s = new String("hello");
The literal "hello" will cause an object in the string constant pool to be created. The new String will create a new String object on the heap, with a copy of the content of the object for the literal.
You should never create String object like that, because it's unnecessary and inefficient.
There are however other reasons why you would want to do new String(...), when the value that you pass to the constructor is not a string literal. For example, the value is data read from a file.
Case 1: String object using string literal. It creates one object in string constant pool
Correct.
if,it is not present
Wrong. It is present.
otherwise, return the reference of this object.
It always return the reference of the object. No 'otherwise' about it.
This object is implicitly interned.
Not really. It is already interned, because it is a string literal. The compiler and class loader see to that. Not thenew operator.
Case 2:String object using new(). it creates 2 objects,one in string constant pool
Not really. It was already there: see above.
and another one in heap area.
Correct.
Reference variable refer to the heap area object.For this object we need to call intern method to put this object into string constant pool explicitly.
Correct.
My question is if new() already creates one object in string constant pool
It doesn't. See above.
This question already has answers here:
What is the difference between "text" and new String("text")?
(13 answers)
Closed 2 years ago.
String s="hi";
String s1=new String("hi");
In memory perspective, where are s and s1 stored? whether it is in heap memory or stack.
And s points "hi" and s1 points to memory location of where hi exists?
Please help?
Consider following
String s = "hi";
String s1 = new String("hi");
variable s will refer to the string literal hi that is referenced from String constant pool and if there are some more variables like s2 = "hi", then s and s2 will refer to same object.
String s1 = new String("hi");
This will create a new String at runtime.
In first case ,all the strnig literals are created when class is loaded in JVM
In seconds case, string objects are created when new String() is executed.
You can find a good tutorial about string constant pool at following link
http://www.thejavageek.com/2013/06/19/the-string-constant-pool/
String s="hi";
This statements creates the String object containing "hi" on the String pool.
String s1=new String("hi");
This statement creates a String object containing "hi" on the heap memory and a copy of it on StringPool (if "Hi" is not contained in stringPool).But here, S will point to the object on heap.
At class loading time, all String literals will be placed in pool. When you use new String("hi") an object will be created on heap. s and s1 are reference variables , it should reside in the method call stack ! The string literal "hi" will be handled by the JVM, by creating a String object on the heap, and having a reference to it from the String pool. The new operator merely takes the string object, whose reference is passed in the constructor, and create a new object. It just so happens that the string being passed to the constructor is a literal.
"hi" is a String literal. This gets created once in the String Constant Pool. In Java 7 that's in the Heap with other objects, but prior to that it was created in the Perm-Gen
String s = "hi";
String s1 = new String("hi");
new String("hi") creates a new String object on the heap, separate from the existing one.
s and s1 are references to the two separate objects. References themselves actually live on the stack, even though they point to objects in the heap.
s and s1 are just references to the strings, therefore they will be stored on the stack, unlike the string instances that are referenced by s and s1. In this case the value that s refers to will be put in the string pool whereas the value refered by s1 won't. Why? because the constructor of a string has been used to make that string. Only literals are pooled, and even if you chose those literals to be concatenations of other literals ( for example, if you have made String s2 = "h" + "i" then s and s2 would point to the same instance of a string that was stored in the string pool).
This leads to a little trap though: because pooled strings point to the same object it is tempting to use == operator instead of equals method to compare strings, which is just dangerous, because there are scenarios where == is the same as equals() but there are a lot more where == will have a different result than the equals() method.
Above answers are correct but shouldn't you use String *s1 = new String("hi") in place ofString s1 = new String("hi") ,as call to new will be returning a pointer to the string object.
I am fairly new to C++. Excuse me, if I am wrong.
PS: I am using the gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC).
According to me when we create String using literal like String s="hello"
s object will reference the String "hello" that is stored in the String Constant pool.
If we will create the new String using New keyword like String s = new String("hello") then in this case two object is created. object s referenced the another object that is stored in the normal heap area and this object will referenced the String Hello that is stored in the String constant pool.
For more details please follow the link:-http://www.javatpoint.com/java-string
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 ?
Please let me know
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.?
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.
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.
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.
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.
This question already has answers here:
What is the purpose of the expression "new String(...)" in Java?
(9 answers)
Closed 10 years ago.
What exactly is the difference between the two statement
String s1="abc";
String s2=new String("abc");
From what i Know is that the first statement will create a object in String pool i.e and s1 will reefer it.
In Second statement the it will create two object because I used new keyword and s2 will refer the object in String pool
Now if I execute both statement one after another .Since will the first statement the object "abc" will be in string pool and with the execution of second statement s2 will refer to object which is alreday there in string pool is if i do s1==s2 it should return true however its returning false.
can you please explain why?
The fact is String s1="abc" allocates the string inside the string pool, which is a special place in which immutable strings are kept. You won't be able to modify directly "abc" but just the reference (s1) which points to it.
In the second case String s2=new String("abc") you are allocating a real string object that internally has a char[] buffer in which the string data is stored. It's immutable like the first one but it's an object onto the heap.
When you compare s1 == s2, since you are comparing references, they are different because one points to the string in the string pool (I'm actually unsure if a wrapper object is created or a direct reference to the object in the pool is used) while the second one points to the object that you created explicitly (which wraps a char[] buffer in which the data is stored).
you are creating two different objects. s1 has its own memory to hold its reference address. Same with s2. Though both of these objects point to the same string in the string pool, the objects themselves are distinct. Therefore, s1==s2 will fail.
s1.equals(s2), however, will work since you are comparing the string contents