• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

string pool behavior

 
Ranch Hand
Posts: 209
13
VI Editor
  • Likes 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm trying to write a few tests to explore the behavior of the string pool.

My understanding is that any string literal appearing in the source code will get placed in the string pool.


So, at line 4, the strings "hello" and "world" will individually be in the pool, but not the string "hello world".
s0.intern() should therefore put the string "hello world" into the pool, where it was not present previously, and s0 and s1 should reference different objects. But they don't.

output:

Could anyone tell me why not?
 
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Richard Hayward wrote:Could anyone tell me why not?


The intern() method works differently than your expectations

From the javadoc of the intern() method

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.


In your example, the string "hello world" is not yet in the pool, so we have to focus on the second part of the above quote. In this case the intern() method will add the String object (referred by s0) to the pool. But no new String object is created and thus the same reference is returned. So that part of the intern() method could look like thisSo that's why s0 and s1 are referring to the same object.

If you add a copy of s0 to your code snippet, you'll notice that it refers to a different String object than s0 (or s1)And what happens if the String "hello world" was already present in the String Literal pool? Then the first part of the aforementioned quote is applicable, so s0 and s1 will refer to different objects, again illustrated in the following code snippet

Hope it helps!
Kind regards,
Roel
 
Richard Hayward
Ranch Hand
Posts: 209
13
VI Editor
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ah, thanks Roel.

Hope it helps!


Certainly yes! I had the wrong mental picture of what's going on there.

Could I additionally ask about garbage collection for strings in the pool?

Is there a difference, with respect to GC, between strings placed in the pool as a result of a source code literal and those placed there as a result of intern()?

I'm thinking that strings in the pool as a result of a source code literal are not subject to GC. However, attempting to test that, for strings in the pool as a consequence of intern():


as already discussed, but

indicating such strings are subject to GC. I realize that GC doesn't necessarily run just because I suggest that it does.
 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Richard Hayward wrote:Is there a difference, with respect to GC, between strings placed in the pool as a result of a source code literal and those placed there as a result of intern()?


Again from the javadoc of the intern() method

All literal strings and string-valued constant expressions are interned. String literals are defined in section 3.10.5 of the The Java™ Language Specification.



Luckily you don't need to worry about strings and GC on the actual exam...
 
Richard Hayward
Ranch Hand
Posts: 209
13
VI Editor
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for your help Roel.

Roel De Nijs wrote:
Again from the javadoc of the intern() method

All literal strings and string-valued constant expressions are interned. String literals are defined in section 3.10.5 of the The Java™ Language Specification.



Ok, literals are interned, but I'm wondering if interned literals are still eligible for GC. Attempting to test that:

it's hard to tell. Maybe GC  didn't run or maybe it did, but strings in the pool put there as a result of appearing as literals in the source are not eligable for GC.

Roel De Nijs wrote:
Luckily you don't need to worry about strings and GC on the actual exam...


Anyway, if it's not needed for the exam, perhaps it's best for me to stop nitpicking over this particular issue.
 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Richard Hayward wrote:Ok, literals are interned, but I'm wondering if interned literals are still eligible for GC.


They probably are, but it will be (very) hard to test. For more info read this excellent article about the String.intern() method in Java 6, 7 and 8.
 
Ranch Hand
Posts: 86
18
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
They are eligible for GC if the corresponding Class (and Classloader) is eligible for GC, i.e. the following prints true, false, true:
 
Sheriff
Posts: 9707
43
Android Google Web Toolkit Hibernate IntelliJ IDE Spring Java
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Although this is old, but on Java 6 or before since the pool was in PermGen, so following code results in false as the intern method call creates a new String in PermGen and s0 and s1 refer to different String objects:

 
Richard Hayward
Ranch Hand
Posts: 209
13
VI Editor
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tobias Bachert wrote:They are eligible for GC if the corresponding Class (and Classloader) is eligible for GC, i.e. the following prints true, false, true:



Thanks Tobias, took me a little while to figure out what your example is doing, but that's instructive.
 
Greenhorn
Posts: 17
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi All,

String s1 = "Hello".concat("World");
String s3 = new String("HelloWorld"); //Line-2
String s2 = s1.intern();
System.out.println(s1 == s2); //false
System.out.println(s1 == s3); //false
System.out.println(s2 == s3); //false

If I removed Line-2 and compare s1==s2, it will return true. Could anyone explain me what exactly happens in string pool after Line-2?

Thanks
 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

salman khandu wrote:Could anyone explain me what exactly happens in string pool after Line-2?


That's already explained very well in this post.
 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi All,

Here I am getting confused with following two lines of code.

1) String s3 = new String("HelloWorld"); will return false for line System.out.println(s1 == s2);
2) String s3 = new String(s1); will return true for line System.out.println(s1 == s2);

What is the difference?
Can anyone please explain?

Thanks
 
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

salman khandu wrote:
If I removed Line-2 and compare s1==s2, it will return true. Could anyone explain me what exactly happens in string pool after Line-2?



First, with line 2 in the program, "HelloWorld" is a string literal, and hence, it is in the string pool at the start of the program.

The s1 reference is assigned to a new instance -- due to the concat() call. The s2 reference is assigned to the instance in the string pool. These two are two different instances, and hence, the comparison is false.


Second, with line 2 not in the program, there is no "HelloWorld" string literal, and hence, no "HelloWorld" in the string pool at the start of the program.

The s1 reference is assigned to a new instance -- due to the concat() call. The intern() call will actually place the s1 instance into the pool, since "HelloWorld" is not in the pool. The s2 reference is then assigned to the instance in the string pool. And hence, s1 and s2 are pointing to the same instance, and hence, the comparison is true.

Henry
 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Bhavin Akolkar wrote:1) String s3 = new String("HelloWorld"); will return false for line System.out.println(s1 == s2);
2) String s3 = new String(s1); will return true for line System.out.println(s1 == s2);

What is the difference?
Can anyone please explain?


In short, in (1) "HelloWorld" is a string literal and it is in String Literal Pool at the start of the program; in (2) that's not the case. That's the difference and results in a different outcome for the s1 == s2 comparison. For a more detailed explanation please refer to this post.
 
Tobias Bachert
Ranch Hand
Posts: 86
18
  • Likes 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Small correction: String literals are loaded lazily at first usage, not at the start of the program/loading of the class (behavior is not defined by the JVM specification).
 
Ranch Hand
Posts: 145
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


1.When the class loads, all the literals in the program are in put in the pool. so is it correct that when the class loads and all the literals are being placed in the pool,  "xyz" will have a pool reference but will not yet be assigned to instance variable d ! Only on lines 8 and 9 , when instances are created, will the respective d instance variables, for s1 and s2 respectively, will be assigned their references from the pool . Am I right ?

2.But if String d was a local variable inside main(), and not an instance variable , will d will be assigned the reference from the String pool when the class loads , or when its statement actually runs/executes ?
 
Marshal
Posts: 8856
637
Mac OS X VI Editor BSD Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Richard, Cowgratulations, your topic has been published in our July's Edition Journal.
 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


"hello " and "world" are located in the String Pool
is "hello world" located in it as well? If not, where is it? Only in the Heap?
What happens between the Heap and the String Pool when
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic