I'm studying Java 8 OCA 1Z0-808 using the book by Jeanne Boyarsky and Scott Selikoff.

In chapter 3 page 111, I am confused about whether it is string pool or String object. See the following code.
The book says it will create 27 String objects and these 27 String objects will be immediately available for garbage collection.
So my guess is, "" is a String object? Line 10. It looks like a string literal to me and should be in string pool?
And also any String concatenation is String object? Line 12
Another question is that I know String object can be garbage collected. What about literals in the string pool? Do they get garbage collected?

Thanks,
Henry

Post by:praveen kumaar
, Ranch Hand

Jan 21, 2017 21:58:31
(2 likes)

Hi Henry,
I don't have that book but may be this could help.
whenever you see a String literal or a String object(created with new keyword) then note it that they both are Object present or created on the heap.
you should have a question that what is a difference b/w the 2 ?
JVM maintains a String Pool(internally) where it contains an implicit reference to the String object referred through a String literal in your code.In other words when your class file is loaded in the JVM it checks for any string literal in there if it founds a one then it creates an object on heap and implicitly create a reference to that object and put that reference in the pool(you cannot have any control over this reference).

Another question may be what did we gain from it ?
this pool provides a String Interning.means if any where in your program if the same string is needed for use(i mean if the same literal is used again in your code) then jvm will use the same copy.

where as the whenever you will create a String object using new keyword then it will always create a new copy on the heap.

Henry wrote:So my guess is, "" is a String object? Line 10. It looks like a string literal to me and should be in string pool?

Yes it is a String Object though it is created internally.and yes it is a string literal and jvm has an implicit reference to this object in a pool.

Henry wrote:And also any String concatenation is String object? Line 12

Yes String concatenation is an Object too but again it is created internally(if the pool has already reference to that object then in that case it will not create the new one as per string interning).

Henry wrote:Another question is that I know String object can be garbage collected. What about literals in the string pool? Do they get garbage collected?

As i have told you that String pool does not contain the object but a implicit reference to that literals so due to these active references they are not eligible for garbage collection(never).

praveen kumaar wrote:Yes String concatenation is an Object too but again it is created internally(if the pool has already reference to that object then in that case it will not create the new one as per string interning).

This is not correct. Strings are only interned when you use a String literal, or when you call String.intern() or any other method that calls String.intern().

The + operator returns a new String object, but it is not interned.

In this particular example, the initial value of alpha is interned, because it's initialized with a String literal.

Every time current gets appended to alpha, a new String object is created, but that new object will not be interned. Because alpha is overwritten each time, the previous value will become eligible for garbage collection, except "" because it's in the string pool, and "abcdefghijklmnopqrstuvwxyz", because it's not overwritten and alpha still has a reference to it. That last string will become eligible for garbage collection when the method body finishes executing.

Post by:Roel De Nijs
, Sheriff

Jan 22, 2017 09:29:06
(1 like)

henry leu wrote:The book says it will create 27 String objects and these 27 String objects will be immediately available for garbage collection.
So my guess is, "" is a String object? Line 10. It looks like a string literal to me and should be in string pool?
And also any String concatenation is String object? Line 12
Another question is that I know String object can be garbage collected. What about literals in the string pool? Do they get garbage collected?

This topic has a great explanation (with additional code snippets) about the same code snippet. Definitely worth reading!

Post by:henry leu
, Greenhorn

Jan 22, 2017 16:20:52

Thanks for all the answers!

But I still have one question.

After line 2, we should have 2 Strings objects in the heap, right? "java" and "c++". What about after line 3? Do we get 2 String objects or 3 String objects on the heap?

For line 3, s2.intern() will check the string pool table and see if "c++" exists. This case it doesn't exist. So "c++" will be added to the string pool. Now, will Java create another new String object on the heap, another "c++" object?

What reference will s3 receive?

Post by:Stephan van Hulst
, Saloon Keeper

Jan 22, 2017 16:42:50
(1 like)

After line 2, there are two strings in the pool: "java" and "c++", because both have been created using a string literal. There also exists a third string object with the same value as "c++", but it's a different object that has not been interned.

At line 3, the object referenced by s2 has its value compared to that of the strings in the string pool. Since it equals "c++" which is already in the string pool, the intern() method won't save the object to the string pool, and it will return a reference to the original object that was created by using the string literal "c++".

You can test this by saving the reference to the original object, getting the interned version of the new object, and comparing them by reference:

Post by:henry leu
, Greenhorn

Jan 22, 2017 17:01:53

henry leu wrote:Thanks for all the answers!

But I still have one question.

After line 2, we should have 2 Strings objects in the heap, right? "java" and "c++". What about after line 3? Do we get 2 String objects or 3 String objects on the heap?

For line 3, s2.intern() will check the string pool table and see if "c++" exists. This case it doesn't exist. So "c++" will be added to the string pool. Now, will Java create another new String object on the heap, another "c++" object?

What reference will s3 receive?

See the attached picture for my understanding of the code above. Please verify if this is correct.

Thanks!

Post by:henry leu
, Greenhorn

Jan 22, 2017 17:07:26
(3 likes, 2 cows)

henry leu wrote:Thanks for all the answers!

But I still have one question.

After line 2, we should have 2 Strings objects in the heap, right? "java" and "c++". What about after line 3? Do we get 2 String objects or 3 String objects on the heap?

For line 3, s2.intern() will check the string pool table and see if "c++" exists. This case it doesn't exist. So "c++" will be added to the string pool. Now, will Java create another new String object on the heap, another "c++" object?

What reference will s3 receive?

IMG_20170122_185406.jpg

Post by:Stephan van Hulst
, Saloon Keeper

Jan 22, 2017 17:13:47

Your drawing is correct.

Post by:Roel De Nijs
, Sheriff

Jan 22, 2017 23:35:54
(2 likes)

I like to add two things.

First of all, this article has an excellent explanation about String literals and the String Literal Pool. Definitely worth reading!

Secondly, here's another topic about the intern() method, but please keep in mind that the intern() method is not on the OCAJP exam.

Post by:Roel De Nijs
, Sheriff

Jan 22, 2017 23:36:57

henry leu wrote:See the attached picture for my understanding of the code above. Please verify if this is correct.

Stephan wrote:This is not correct. Strings are only interned when you use a String literal, or when you call String.intern() or any other method that calls String.intern().

The + operator returns a new String object, but it is not interned...

Stephan,Thanks for mentioning it but saying that "+" will not intern the string is not
true for the case below where i had use it to concatenate 2 String literal.

Post by:Stephan van Hulst
, Saloon Keeper

Jan 23, 2017 04:15:56
(1 like)

That is probably because the compiler is smart enough to rewrite "Step"+"han" to "Stephan", which gets added to the String pool when the application starts.

Try this instead:

Post by:praveen kumaar
, Ranch Hand

Jan 23, 2017 05:33:01

Okay I got it Stephan,Thanks.
But as far as the Garbage collection of the Interned String is concerned i found that Interned Strings can be Garbage Collectable→These are not my words actually i found it here.
I will request both of you,@Roel and @Stephan,to look in this link and please let me know if it's correct.

Kind Regards,
Praveen.

Post by:Stephan van Hulst
, Saloon Keeper

Jan 23, 2017 06:13:01

I suppose a valid implementation of the string pool could use soft references to strings, meaning that interned strings get garbage collected when there are no strong references to them anymore.

I'm not sure if this actually happens though. I imagine that for most applications, only literals are interned and if the developer crashes their machine by interning too many strings, so be it.

Post by:Roel De Nijs
, Sheriff

Jan 23, 2017 11:59:56

praveen kumaar wrote:But as far as the Garbage collection of the Interned String is concerned i found that Interned Strings can be Garbage Collectable

Honestly I don't really care! Not for the OCAJP exam (because the intern() method is not on the exam), nor for my real life development (I have been a Java developer since 2004 and never had to use the intern() method).

It would be strange/weird/inconsistent if String literals behave differently regarding GC than all other objects in Java. So it makes sense that all strings in the JVM string pool are eligible for GC if there are no references to them from your application. Here is another article confirming this behavior.

Post by:praveen kumaar
, Ranch Hand

Jan 25, 2017 22:30:50
(0 likes, 2 cows)

Stephan wrote:That is probably because the compiler is smart enough to rewrite "Step"+"han" to "Stephan", which gets added to the String pool when the application starts.

Yes you are completely correct.next time you can just remove the the word "probably" from your quote.i have try disassembling this code:
Here is the Disassembled code:

You can easily view the difference:using "+" on the 2 string references make use of a StringBuilder object and its append method and in contrast using "+" on 2 String literals directly is easily interpreted as the resultant string constant(so is interned).

Kind Regards,
Praveen.

Post by:Stephan van Hulst
, Saloon Keeper

Jan 26, 2017 03:43:51

I'm actually really surprised that the compiler doesn't inline the two String literals (and then reduces it further by eliminating the concatenation), because step and han are effectively final. That's the reason I used overridable method calls instead of variables.

Oh well. Nice job, have a cow!

Post by:Roel De Nijs
, Sheriff

Jan 27, 2017 20:53:10

Stephan van Hulst wrote:I'm actually really surprised that the compiler doesn't inline the two String literals (and then reduces it further by eliminating the concatenation), because step and han are effectively final.

That's probably because in the class Test (which praveen used to decompile) the reference variables step and han are not declared final. This code snippetresults in the following byte codeNo use of StringBuilders here. That compiler is really one smart cookie!

Disclaimer: this is waaaaaaaaaaaay beyond the scope of the OCAJP (and even OCPJP) certification exam.

Post by:praveen kumaar
, Ranch Hand

Jan 27, 2017 21:33:33

Roel,in my case it make use of a StringBuilder is it because compiler cannot be sure that variable step and han will always point to the literal step and han resectively and in your case the final modifier has make the variable compile time constants(so the compiler will put the respective literal accordingly with step and han wherever these variables are used).
but when i tried to decompile it,i got:

In my case it doesn't even loads the String literal "step" and "han".can you explain,why?
Another thing is here again both stephan_1 and stephan_2 are interned.

Anyway,i am not preparing for OCAJP or any exams.i just love to learn new things and add it to my knowledge(i don't have any instructor or guide so i have to learn by myself,that's why i am asking these much things).Hope these things will not annoy you.

Kind regards,
Praveen.

Post by:Femy Anish
, Greenhorn

Jan 30, 2017 01:10:03

Hi,

I'm also preparing for Java 8 OCA 1Z0-808 using the book by Jeanne Boyarsky and Scott Selikoff.

I too have a doubt regarding String literal and String object.My simple question is if we type String str = "abc". Do it create only a literal in the String pool or will it create a String object in the heap.

Post by:praveen kumaar
, Ranch Hand

Jan 30, 2017 01:32:52

Hi Femy,
Welcome to CodeRanch! simply explore through all the replies in this post and their were links given by @Roel go through them,you will get your doubts clear.even then if you have any doubts unclear,create a new topic and inside it tell us about your query we will guide to sort your problem there.

kind regards,
praveen.

Post by:Femy Anish
, Greenhorn

Jan 30, 2017 03:09:55

Thanks for the Reply.

I will go through the previous replies and link and will get back in case of doubt.

My guess would be "compiler optimization". The compiler sees you are trying to concatenate two Strings which are also compile-time constants and performs these String concatenations at compile-time (and save a few CPU cycles at run-time).

Post by:Umberto D'Ovidio
, Greenhorn

Feb 12, 2017 15:39:54

Femy Anish wrote:Hi,

I'm also preparing for Java 8 OCA 1Z0-808 using the book by Jeanne Boyarsky and Scott Selikoff.

I too have a doubt regarding String literal and String object.My simple question is if we type String str = "abc". Do it create only a literal in the String pool or will it create a String object in the heap.

It creates also an object in the heap, which is referenced by the literal in the string pool

Post by:Roel De Nijs
, Sheriff

Apr 12, 2017 08:06:59

Femy Anish wrote:I too have a doubt regarding String literal and String object.My simple question is if we type String str = "abc". Do it create only a literal in the String pool or will it create a String object in the heap.

The String object "abc" is created on the heap and a reference (address) to this object is stored in the String Literal Pool, so only one object will be created.