4
String str = new String("Hello");

Normally I have read, in many articles available on internet, that two objects are created when we write the statement above. One String object is created on the heap and one string object is created on the Literal Pool. And the heap object is also referring the object created on Literal Pool. (Please correct this statement of mine if it is wrong.)

Please note that the above explanation is as per my understanding after reading some articles on internet.

So my question is.. Are there any ways available to stop creating the string object in literal pool. How it can be done?

[Please let me know about the best link for understanding of this Literal Pool, How is it implemented]

Community
  • 1
  • 1
Sunny Gupta
  • 6,929
  • 15
  • 52
  • 80

2 Answers2

6

There's only ever be one string with the contents "Hello" in the literal pool. Any code which uses a string constant with the value "Hello" will share a reference to that object. So normally your statement would create one new String object each time it executed. That String constructor will (IIRC) create a copy of the underlying data from the string reference passed into it, so actually by the time the constructor has completed, the two objects will have no references in common. (That's an implementation detail, admittedly. It makes sense when the string reference you pass in is a view onto a larger char[] - one reason for calling this constructor is to avoid hanging onto a large char[] unnecessarily.)

The string pool is used to reduce the number of objects created due to constant string expressions in code. For example:

String a = "Hello";
String b = "He" + "llo";
String c = new String(a);

boolean ab = a == b; // Guaranteed to be true
boolean ac = a == c; // Guaranteed to be false

So a and b refer to the same string object (from the pool) but c refers to a different object.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • You mean to say as soon as the constructor gets executed the two objects have nothing in common, then where exactly it stores the second "a" object ("c" object's content) in case of String c = new String(a). – Sunny Gupta Jan 18 '12 at 18:06
  • @sunny: It creates a copy in a new char[]. That's what holds the data in the long run. – Jon Skeet Jan 18 '12 at 18:13
  • Just one more clarificaion, You mean to say two char[] will be there one on literal pool and one on heap. right?? – Sunny Gupta Jan 18 '12 at 18:19
  • whenever you find time please respond..waiting for your response – Sunny Gupta Jan 18 '12 at 18:25
  • @JonSkeet: This article has me quite uneasy - I'm still in university and they have primarily taught us Java as our language. We've taken a 'machine level' programming course that showed us how the C programming language works at a low level (Its runtime stack, heap, stack frames, etc) and why it is terribly unsafe to certain things due to how it is executed down there.. I know Java works entirely differently, running on the VM but other than that.. Is there something I should read to learn a similar understanding for Java? Everyone on here seems to have this deep understanding I simply don't. – Alex Jan 18 '12 at 18:27
  • 2
    @Alex: It's mostly something you get through experience. I'd thoroughly recommend reading Effective Java, 2nd edition by Josh Bloch though. – Jon Skeet Jan 18 '12 at 18:35
  • @sunnygupta: Please don't post "prodding" comments like that - a mere 6 minutes after your previous comment! The two `char[]` objects themselves aren't really in the pool; it's a pool of String references. However, one of them will be referred to by a string in the pool, and the other will be referred to by the new string which *isn't* in the pool. – Jon Skeet Jan 18 '12 at 18:36
  • @JonSkeet: Thanks, I looked it up and read an interview where he talks about the book.. It seems like it talks about the kind of things I was looking to know that keep popping up on this site. Ugh, I guess I will just have to keep pushing leaning iPhone/Objective C development back :S Probably better to focus on Java while I am on a 4-month work term where I am using it exclusively than to confuse things by working on the ins and outs of another language. Thanks for the recommendation though! I'll probably go try to hunt that down today. – Alex Jan 18 '12 at 19:09
2

If I understand your question correctly, you're asking how to initialize a string without placing it in the string literal pool. You can avoid this as long as you don't declare a string literal expression (don't declare a series of characters in double quotes.)

// these two strings will be placed in the string literal pool
String one = "one";             
String two = new String("two");
// this third string will NOT be placed in the string literal pool
String three = new String(new char[] {'t', 'h', 'r', 'e', 'e'});
piepera
  • 2,033
  • 1
  • 20
  • 21
  • 2
    In your example there will be a String `"two"` in the string pool but the String instance referenced by the variable `two` will be a different object that has it's data copied from `"two"`. – x4u Jan 18 '12 at 18:12
  • Nice thought...I appreciate that – Sunny Gupta Jan 18 '12 at 18:12
  • @x4u...thanks for the info ,but how one can prove this...can we count the diff in the no of objects created before executing String two = new String("two"); and after executing this(ans as you say is 2).... – lowLatency Apr 22 '12 at 07:54
  • String two will go to string literal pool after doing two.intern() – Praveen Kumar Feb 14 '13 at 14:27
  • That's not quite accurate -- the string "two" is already in the string literal pool after the above code is executed. Nothing will "go to the string literal pool" by invoking two.intern(). However, if you invoke three.intern(), then the string "three" will "go to the string literal pool". – piepera Mar 22 '13 at 20:44