• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

String Constant Pool

 
dennis zined
Ranch Hand
Posts: 330
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello ranchers.
According to K&B book, in the statement: String s = new String("abc");
Java will create a new String object in normal (nonpool) memory, and s will refer to it. In addition, the literal �abc� will be placed in the pool.

But according to Klalid Mughal:

"Note that using a constructor creates a brand new String object, that is, using a constructor does not intern the string."

Who is correct? Are strings interned / stored in the pool when used with a constructor or not (String s = new String("abc"))?
Thanks.
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24208
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Both statements are correct. The constructor invocation has nothing to do with the String pool. Writing
String s = "abc";
would also cause "abc" to be added to the String pool. It's the String literal that is added to the pool, not any String created using "new".
 
Nathaniel Stoddard
Ranch Hand
Posts: 1258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, I think semantically they are both correct, although that second one is a bit confusing .. "intern" ??
String s = new String("Hi");
will create one string in the constant string pool with a value of "Hi". When the String constructor is called, it will be given an argument of a String (already in existence) -- the one in the constant string pool. And so, in the end you have two strings.
String s = "Hi";
will of course only create one string, which will be on the constant string pool.
Now, that second statement you quoted says that when you do:
String t = new String("lkj");
String s = new String(t);
the second string (s) will create a new String (on the heap) instead of merely wrapping or somehow pointing to the first string. In the end, you'll have 3 string values.
-- Personally, I'd stay away from that second definition (what's up with the word intern anyways -- sheesh). Just remember that if you put a literal in your code for a string it's going to be created and placed in the constant string pool. After that, any time you use the new operator on a String constructor you're going to be creating a separate String object on the heap.
Inevitably they're going to ask you on the exam to count the number of strings created by some code. So just add up all the literals and the "news" and you should be okay. Forget about Monica and all her little interns.
 
Vad Fogel
Ranch Hand
Posts: 504
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kathy & Bert must be correct. Let's see the byte code for a small test class:
Source Code:

Byte Code:

Line 0 creates a new String object on the heap. Line 4 accesses a String constant in the constant pool.
Let's refer JVM Specs, Chapter 7.4 on that:

Many numeric constants, as well as objects, fields, and methods, are accessed via the constant pool of the current class. Object access is considered later (�7.8). Java data of types int, long, float, and double, as well as references to instances of String (constant pool items tagged CONSTANT_String), is managed using the ldc, ldc_w, and ldc2_w instructions.


Here's the byte code:

The new String is gone, there's only one interned String literal now. Hope this helps.
[ December 10, 2003: Message edited by: Vad Fogel ]
 
dennis zined
Ranch Hand
Posts: 330
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi..thanks for your posts, just a follow-up question.
So in both cases:
String str=new String("abc"); and
String str="abc";
"abc" will exist only once in the String pool?
Then what is the purpose of intern method of the String class?
The jdk 1.4 source code for the intern() method of String says (Nathaniel, hope you're reading this):
"When the intern method is invoked, if the pool already contains a
string equal to this <code>String</code> object as determined by
the {@link #equals(Object)} method, then the string from the pool is
returned. Otherwise, this <code>String</code> object is added to the
pool and a reference to this <code>String</code> object is returned."
Does this mean not all strings will be in the pool? And by calling
the intern method, its like you're instructing JVM to put it there so other variables can reuse it?
Thanks.
 
dennis zined
Ranch Hand
Posts: 330
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here's what I dug up from JLS:

Each string literal is a reference (�4.3) to an instance (�4.3.1, �12.5) of class String (�4.3.3). String objects have a constant value. String literals�or, more generally, strings that are the values of constant expressions (�15.28)�are �interned� so as to share unique instances, using the method String.intern.
...
...
The result of explicitly interning a computed string is the same string as any pre-existing literal string with the same contents.

You guys are right. So both
String str=new String("abc"); and
String str="abc";
are placed at the String pool. But a computed string is not and by using the intern method, you are in effect putting it in a pool for possible use by other variables.
Thanks again guys.

Vad, thanks for the byte code representation..i hope i can learn to interpret them, i'm sure it will help me a lot.
 
Nathaniel Stoddard
Ranch Hand
Posts: 1258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Wow. I guess I can be thankful that the whole "intern" thing didn't come up when I had to take the exam.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic