Reputation: 554
The commonly agreed answer to this interview question is that two objects are created by the code. But I don't think so; I wrote some code to confirm.
public class StringTest {
public static void main(String[] args) {
String s1 = "a";
String s2 = "a";
String s3 = new String("a");
System.out.println("s1: "+s1.hashCode());
System.out.println("s2: "+s2.hashCode());
System.out.println("s3: "+s3.hashCode());
}
}
The output is:
Does this mean that only one object was created?
Reaffirm: My question is how many object was created by the following code:
String s = new String("xyz")
Instead of the StringTest
code.
Inspired by @Don Branson, I debugged the below code:
public class test {
public static void main(String[] args) {
String s = new String("abc");
}
}
And the result is:
The id of s is 84, and the id of "abc" is 82. What exactly does this mean?
Upvotes: 31
Views: 151137
Reputation: 31
It creates 2 Objects . We can debug and see . . When we pass value as new String("XYZ") the constructor involved created a Object for original variable. Observe id=26 .
Now the String S1 id is different in String S1 = new String("XYZ"); but String s2 = "XYZ" id will be same as original variable also reference address of Objects are different and S1.intern and S2 has same reference address . So 2 Objects are getting created one in SCP (because intern and literal are referring same Object) and one in Heap.
Upvotes: 0
Reputation: 4069
2 objects made out of:
String s = new String("xyz");
1st creating new String object in heap memory (String Pool)
2nd placing "xyz"
in string constant pool
Upvotes: 0
Reputation: 21
There are so many random answers and so I am confident that my interviewer will also be not very sure :) :)
I researched a lot and found that hashcode is not the memory address and the variables while debugging don't give the memory address. So, those parameters might confuse.
Upvotes: 2
Reputation: 49
If new String() creates 2 objects (one in heap and one in String pool) then what is the use of .intern method ?
intern() method invoked on a String object looks for the string contained by this String object in the pool, if the string is found there then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
Upvotes: 0
Reputation: 1367
Confused with what exactly happens after the new String("<>") is being called, I found this thread. Your hashcode comparison understanding is not technically correct though.
int hashCode() has been overriden in String class and it returns a value depending on the content of the String literal.
String s1 = new String("Hello"); String s2 = new String("Hello");
So s1.hashCode() = s2.hashCode() = anyStringOfContent_"Hello".hashCode()
**/** Cache the hash code for the string */
private int hash; // Default to 0
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
**h = 31 * h + val[i];**
}
hash = h;
}
return h;
}**
Now just to explain why is this done, you can actually read the Kathy Sierra book which has a great explanation why developers have done in this manner (basically any objects returning true to equals() method should return same hashCode() value).
Upvotes: 0
Reputation: 1
String s = new String("xyz");
how many objects has been created in above code?
Only one object has been created in above code, that's in heap memory.
not two object.....
If two objects are created, one is in a heap memory(new operator) and another one is in String constant pool(string literal), if your store below value using String literal ,
String s1 = "xyz";
it will not returns reference of object s in string constant pool. it will create new object in String Constant Pool as s1.
How?
we can check it by using == operator (s == s1) to check the reference type. If s is already stored in String Constant Pool it give the true, in this case output is false.
So the conclusion is one object is created in above code.
Upvotes: -3
Reputation: 16
If we run below code in eclipse in debug mode we'll get an idea about how many objects are created with String string = new String("manoj");
Internally it will create String str = "manoj"
in String class constructor.
Just check id after hover on reference as shown in below screen shot.
ScreenShot
public static void main(String[] args)
{
String str = "atul";
String string = new String("manoj");
String string2 = "manoj";
System.out.println(str == string);
}
Upvotes: 0
Reputation: 1555
If we execute String s = new String("Brajesh");
, two objects shall be created. One object will be created in string literal pool and another one in heap area.
But if we have already same string literal object, then only one object is created.
like
String s1 ="Brajesh";
String s = new String("Brajesh");//it will create only one object in heap area
Apart from this one additional object is also created in heap area that is char[]'s object. I have attached here snapshot of heap memory.
Upvotes: 2
Reputation: 443
There are two ways to create string objects in Java:
Using the new operator, i.e.
String s1 = new String("abc");
Using a string literal, i.e.
String s2 = "abc";
Now string allocation is costly in both time and memory so the JVM (Java Virtual Machine) performs some tasks. WHAT TASKS?
See, whenever you are using the new
operator the object is created, and the JVM will not look in the string pool. It is just going to create the object, but when you are using the string literals for creating string objects then the JVM will perform the task of looking in the string pool
I.e., when you write
String s2 = "abc";
the JVM will look in the string pool and check if "abc" already exists or not. If it exists then a reference is returned to the already existing string "abc" and a new object is not created and if it doesn't exists then an object is created.
So in your case (a)
String s1 = new String("abc");
new
is used the object is created(b)
String s2 = "abc";
(c)
String s2 = "abc";
You can also check it out by using the following code:
class String_Check
{
public static void main(String[] n)
{
String s1 = new String("abc");
String s2 = "abc";
String s3 = "abc";
if (s1==s2)
System.out.println("s1==s2");
if(s1==s3)
System.out.println("s1==s3");
if(s2==s3)
System.out.println("s2==s3");
}
}
I hope this helps... Note that ==
is used to see if the objects are equal and the equals(Object)
method is used to see if content are equal.
Upvotes: 3
Reputation: 323
@Giulio, You are right. String s3 = new String("abc"); creates two objects one in heap with reference s3 and another in SCP(Without reference). and now String s2 = "abc"; doesn't create any new object in SCP because "abc" is already there in SCP.
String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
String s4 = s3.intern();
System.out.println("s1: "+System.identityHashCode(s1));
System.out.println("s2: "+System.identityHashCode(s2));
System.out.println("s3: "+System.identityHashCode(s3));
System.out.println("s4: "+System.identityHashCode(s4));
O/P:s1: 366712642, s2: 366712642, s3: 1829164700, s4: 366712642
As i am not eligible for commenting i wrote it here.
Upvotes: 0
Reputation: 13137
First, this question really asks about this addressed here: Is String Literal Pool a collection of references to the String Object, Or a collection of Objects
So, that is a guide for everyone on this matter.
...
String s = new String(“xyz”)
There are two ways of looking at this:
(1) What happens when the line of code executes -- the literal moment it runs in the program?
(2) What is the net effect of how many Objects
are created by the statement?
a) The "xyz"
String
is created and interned when the JVM loads the class
that this line of code is contained in.
"xyz"
is already in the intern pool from some other code, then the literal might produce no new String
object.b) When new String s
is created, the internal char[]
is a copy of the interned"xyz"
string.
c) That means, when the line executes, there is only one additional object created.
The fact is the "xyz"
object will have been created as soon as the class loaded and before this code section was ever run.
...next scenario ...
"a"
)String s1 = "a";
String s2 = "a";
String s3 = new String("a");
a) s1 and s2 are just referenced,not objects, and they point to the same String
in memory.
b) The "a" is interned and is a compound object: one char[]
object and the String
object itself. It consisting of two objects in memory.
c) s3, new String("a")
produces one more object. The new String("a")
does not copy the char[]
of "a", it only references it internally. Here is the method signature:
public String2(String original) {
this.value = original.value;
this.hash = original.hash;
}
One interned String
("a")
equals 2 Objects
. And one new String("a")
equals one more object. Net effect from code is three objects.
Upvotes: 29
Reputation: 37
public String(String original) {
int size = original.count;
char[] originalValue = original.value;
char[] v;
if (originalValue.length > size) {
// The array representing the String is bigger than the new
// String itself. Perhaps this constructor is being called
// in order to trim the baggage, so make a copy of the array.
int off = original.offset;
v = Arrays.copyOfRange(originalValue, off, off+size);
} else {
// The array representing the String is the same
// size as the String, so no point in making a copy.
v = originalValue;
}
this.offset = 0;
this.count = size;
this.value = v;
}
If we see the code , we can see it will just create a char[] and it will get copied every time with same content get instantiated and yes it will store data in String Constant Pool . 1)Will take from SCP String s1 = "a" String s2 = "a"; 2)Creates a new object String s3 = new String("a"); Curiosity , New Object String s2=new String("a"); In all above code same char[] will get copied.i:e char[] value You can check here
Upvotes: 1
Reputation: 11
There is a way to find how many objects are created using the new
keyword (String s1=new String("Rajesh")
).
public class Rajesh {
public static void main(String[] args){
String s1=new String("Rajesh");
System.out.println(s1+s1.intern());
}
}
Output:
RajeshRajesh //s1=Rajesh+s2.intern()=Rajesh
Note: As we know the intern method always hit the string constant pool of heap memory.
Upvotes: -3
Reputation: 129
String s1="Pune";
String s2="Mumbai";
String s3="Pune";
String s4=new String("Mumbai");
System.out.println("S1 :"+s1.hashCode()); //S1 :2499228
System.out.println("S2 :"+s2.hashCode()); //S2 :-1979126203
System.out.println("S3 :"+s3.hashCode()); //S3 :2499228
System.out.println("S4 :"+s4.hashCode()); //S4 :-1979126203
System.out.println(s2==s4); // false
As we can see in the above program we are getting a similar hashcode for s2 and s4 respectively although we are getting false using == operator. == operator is used for reference comparison.
Two objects have been created at "String s4=new String("Mumbai")", one in heap memory and one in stack memory. Therefore s2 compares with s4 which is created in heap memory, not with stack memory.
Upvotes: 1
Reputation: 491
There is a concept called string pool in Java. A string pool (string intern pool) is a special storage area in the Java heap. When a string is created and if the string already exists in the pool, the reference of the existing string will be returned, instead of creating a new object and returning its reference.
So String s = new String(“xyz”)
it will create two objects.
The first object will be created in the Java permanent heap memory as part of the argument we are passing - "XYZ". And it will be created in the String Literal Pool.
The second object will be created within the Java heap memory - which will be created as part of the new
operator.
Upvotes: -2
Reputation: 427
Two objects will be created for this:
String s = new String("abc");
One in the heap and the other in the "string constant pool" (SCP). The reference s
will pointing to s
always, and GC is not allowed in the SCP area, so all objects on SCP will be destroyed automatically at the time of JVM shutdown.
For example:
Here by using a heap object reference we are getting the corresponding SCP object reference by call of intern()
String s1 = new String("abc");
String s2 = s1.intern(); // SCP object reference
System.out.println(s1==s2); // false
String s3 = "abc";
System.out.println(s2==s3); //True s3 reference to SCP object here
Upvotes: 11
Reputation: 1
I used the hashcode()
method to find the number of string objects created.
The hashcode()
method digests the data stored in the reference variable into a single hash value.
CASE1:
String s="
Fred";
System.out.println(s.hashCode());
s=s+"47";
System.out.println(s.hashCode());
s=s.substring(2,5);
System.out.println(s.hashCode());
s=s.toUpperCase();
System.out.println(s.hashCode());
s=s.toString();
System.out.println(s.hashCode());
The output is:
Fred--2198155 //1st object ---------------- String s="Fred"
Fred47--2112428622 //2nd object ---------------- s=s+"47"
ed4--100213 //3rd object ---------------- s=s.substring(2,5)
ED4--68469 //4th object ---------------- s=s.toUpperCase()
ED4--68469 //this is retrieved from the string constant pool -------- s=s.toString();
So 4 objects created in total.
CASE 2:
String s="FRED";
System.out.println(s.hashCode());
s=s+"47";
System.out.println(s.hashCode());
s=s.substring(2,5);
System.out.println(s.hashCode());
s=s.toUpperCase();
System.out.println(s.hashCode());
s=s.toString();
System.out.println(s.hashCode());
The output is:
FRED--2166379 //1st object ---------------- String s="Fred"
FRED47--2081891886 //2nd object ---------------- s=s+"47"
ED4--68469 //3rd object ---------------- s=s.substring(2,5)
ED4--68469 //this is retrieved from the string constant pool ------- s=s.toUpperCase()
ED4--68469 //this is retrieved from the string constant pool -------- s=s.toString()
3 objects created in total.
Upvotes: -3
Reputation: 21718
java.lang.String
overrides the hashCode()
method so that the value depends on the content of the string.
As a result, hashCode()
does not tell you anything about the number of instances. It may be the same string or may be another instance with no single byte shared. Same about equals()
. This explains your output.
Use System.identityHashCode(..) for this kind of research.
And may the source be with you.
Upvotes: 0
Reputation: 1123
Just because all your hash codes are the same does not mean that you are looking at the same object. Two objects are created. Let's break this down.
String s = new String(“xyz”);
In the part ' new String("xyz") ', an address is returned to the new string "xyz". When you say ' String s = ', this assigns that returned address to this object, so that they point to the same place, but the new string and string s are two seperate objects.
Upvotes: -3
Reputation: 13709
I ran it in the Eclipse debugger. In that context, two objects are created, one with the id 17, the other 22:
Upvotes: 0
Reputation: 3230
2 or 3 objects are created, depending on how smart the compiler is.
Nevertheless, your test is junk, because hashCode
of String
s is based on the content of the String
, and not on their identity. If you want to check for identity, you should use System.identityHashCode
or just ==
comparison.
The compiler and the runtime are allowed (not forced) to optimize string creation whenever possible. So, they optimize literal strings, by using a single literal for the three strings you have.
Anyway, the new
operator must return a new object (i.e. a newly allocated one).
String optimization at runtime is possible if the static method String.valueOf
is used instead. But I don't know if any caching is actually applied by current JREs (maybe it's more expensive to check a hash table than to just allocate a new String
)
Upvotes: 1