2

if i create a string object as

String s=new String("Stackoverflow");

will String object created only in heap, or it also makes a copy in String constant pool.

Thanks in advance.

jmj
  • 237,923
  • 42
  • 401
  • 438
  • `String x = "Stackoverflow"` will be placed in constant pool, `String x = new String("Stackoverflow")` will be placed on the `heap` as well as `String s = new String("")`. – Omoro Feb 07 '14 at 07:42
  • You should find a detailed answer here: http://stackoverflow.com/questions/14150628/string-constant-pool-java – Guy Bouallet Feb 07 '14 at 07:46
  • @GuyBouallet note that that answer seems to be contradicting answers given here, as it says it is put to both constant pool and the heap – eis Feb 07 '14 at 07:47
  • 1
    @eis Yes. After the line of code that OP has quoted, the value `"Stackoverflow"` WILL be in the constant pool; and the object referred to by `s` WILL be on the heap. – Dawood ibn Kareem Feb 07 '14 at 07:52
  • Agree with @DavidWallace. In my answer I've given another example with different construct approach, which will not cause a copy in constant pool. – Weibo Li Feb 07 '14 at 08:10

5 Answers5

10

You only get a string into the constant pool if you call intern or use a string literal, as far as I'm aware.

Any time you call new String(...) you just get a regular new String object, regardless of which constructor overload you call.

In your case you're also ensuring that there is a string with contents "Stackoverflow" in the constant pool, by the fact that you're using the string literal at all - but that won't add another one if it's already there. So to split it up:

String x = "Stackoverflow"; // May or may not introduce a new string to the pool
String y = new String(x);   // Just creates a regular object

Additionally, the result of a call to new String(...) will always be a different reference to all previous references - unlike the use of a string literal. For example:

String a = "Stackoverflow";
String b = "Stackoverflow";

String x = new String(a);
String y = new String(a);

System.out.println(a == b); // true due to constant pooling
System.out.println(x == y); // false; different objects

Finally, the exact timing of when a string is added to the constant pool has never been clear to me, nor has it mattered to me. I would guess it might be on class load (all the string constants used by that class, loaded immediately) but it could potentially be on a per-method basis. It's possible to find out for one particular implementation using intern(), but it's never been terribly important to me :)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    Yes, but he DID use a String literal. The literal goes in the constant pool, and the new object goes on the heap. – Dawood ibn Kareem Feb 07 '14 at 07:41
  • 3
    @DavidWallace: But the use of the literal doesn't in itself add to the constant pool - it ensures that the value is *in* the constant pool, but it may already be there. I've clarified this in an edit. – Jon Skeet Feb 07 '14 at 07:43
  • I think the wording of the question implies that the literal wasn't in the constant pool to start with. – Dawood ibn Kareem Feb 07 '14 at 07:44
  • @DavidWallace - 1) I don't read it that way, and 2) the String object corresponding to a String literal is *always* in the string pool. – Stephen C Feb 07 '14 at 07:49
5

In this case you are constructing an entirely new String object and that object won't be shared in the constant pool. Note though that in order to construct your new String() object you actually passed into it a String constant. That String constant is in the constants pool, however the string you created through new does not point to the same one, even though they have the same value.

If you did String s = "Stackoverflow" then s would contain a reference to the instance in the pool, also there are methods to let you add Strings to the pool after they have been created.

Tim B
  • 40,716
  • 16
  • 83
  • 128
  • 1
    `"stackoverflow"` will be in the pool, `s` won't. – assylias Feb 07 '14 at 07:43
  • Yes, so we end up with two copies of `"stackoverflow"` - the literal one in the constant pool, plus `s` on the heap. – Dawood ibn Kareem Feb 07 '14 at 07:47
  • Omoro is correct. In this case the `new String` is being created from a String constant though. So the constant is added to the string pool, from that constant a new String object is created in the heap. – Tim B Feb 07 '14 at 07:47
  • 1
    @TimB, Your (perfectly correct) comment seems to contradict your answer. – Dawood ibn Kareem Feb 07 '14 at 07:48
  • @Omoro the literal `"stack overflow"` is first created and goes to the pool then a new String is creating using the copy constructor which will not be in the pool. – assylias Feb 07 '14 at 07:49
  • Also, opposing pool with heap is misleading: the string pool may well be on the heap too (it is in java 8 for example)... – assylias Feb 07 '14 at 07:50
  • @DavidWallace how does it contradict the answer? He's constructing an entirely new String object so that object won't be shared...the fact that another one is also created that will be shared doesn't invalidate that point. – Tim B Feb 07 '14 at 07:58
  • Well, your answer seems to say that the value doesn't end up in the constant pool; and clearly it does. I believe you understand correctly what happens, but the first sentence of your answer is really quite unclear. I'm wondering if there's a way that you could clarify that you meant that the object referred to by `s` is not in the constant pool, even though the value `"Stackoverflow"` is in the constant pool. That would certainly earn you my upvote. – Dawood ibn Kareem Feb 07 '14 at 08:17
  • @DavidWallace It says that the string instance `s` points to does not go in the pool. There is a different `String` with the same value in the pool but I don't comment on that either way. I've edited the answer to hopefully remove the ambiguity though. – Tim B Feb 07 '14 at 10:39
2

The new String is created in the heap, and NOT in the string pool.

If you want a newly create String to be in the string pool you need to intern() it; i.e.

String s = new String("Stackoverflow").intern();

... except of course that will return the string literal object that you started with!!

String s1 = "Stackoverflow";
String s2 = new String(s1);
String s3 = s2.intern();

System.out.println("s1 == s2 is " + (s1 == s2));
System.out.println("s2 == s3 is " + (s2 == s3));
System.out.println("s1 == s3 is " + (s1 == s3));

should print

s1 == s2 is false
s2 == s3 is false
s1 == s3 is true

And to be pedantic, the String in s is not the String that was created by the new String("StackOverflow") expression. What intern() does is to lookup the its target object in the string pool. If there is already a String in the pool that is equal(Object) to the object being looked up, that is what is returned as the result. In this case, we can guarantee that there will already be an object in the string pool; i.e. the String object that represents the value of the literal.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

A regular java object will be created in the heap, and will have a reference s type of String. And, there will be String literal in String Constant Pool. Both are two different things.

Abimaran Kugathasan
  • 31,165
  • 11
  • 75
  • 105
0

My answer is YES!

Check the following code first:

String s0 = "Stackoverflow";
String s1 = new String("Stackoverflow");
String s2 = s1.intern();

System.out.println(s0 == s1);
System.out.println(s1 == s2 );
System.out.println(s0 == s2);

//OUTPUT:
false
false
true

s0 hold a reference in the string pool, while new String(String original) will always construct a new instance. intern() method of String will return a reference in the string pool with the same value.

Now go back to your question:

Will String object created only in heap, or it also makes a copy in String constant pool?

Since you already wrote a string constant "Stackoverflow" and pass it to your String constructor, so in my opinion, it has the same semantic as:

String s0 = "Stackoverflow";
String s1 = new String(s0);

which means there will be a copy in String constant pool when the code is evaluated.

But, if you construct the String object with following code:

String s = new String("StackoverflowSOMETHINGELSE".toCharArray(),0,13);

there won't be a copy of "Stackoverflow" in constant pool.

Weibo Li
  • 3,565
  • 3
  • 24
  • 36