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 Str
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 :)
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 String
s to the pool after they have been created.
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.
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.
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.