| Author |
String Constant Pool
|
dennis zined
Ranch Hand
Joined: Mar 07, 2003
Posts: 330
|
|
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.
|
SCJP 1.4<br />SCWCD 1.4
|
 |
Ernest Friedman-Hill
author and iconoclast
Marshal
Joined: Jul 08, 2003
Posts: 24041
|
|
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".
|
[Jess in Action][AskingGoodQuestions]
|
 |
Nathaniel Stoddard
Ranch Hand
Joined: May 29, 2003
Posts: 1258
|
|
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.
|
Nathaniel Stodard<br />SCJP, SCJD, SCWCD, SCBCD, SCDJWS, ICAD, ICSD, ICED
|
 |
Vad Fogel
Ranch Hand
Joined: Aug 25, 2003
Posts: 504
|
|
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
Joined: Mar 07, 2003
Posts: 330
|
|
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
Joined: Mar 07, 2003
Posts: 330
|
|
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
Joined: May 29, 2003
Posts: 1258
|
|
|
Wow. I guess I can be thankful that the whole "intern" thing didn't come up when I had to take the exam.
|
 |
 |
|
|
subject: String Constant Pool
|
|
|