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.
publi
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.
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.
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
)
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.
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.
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);
}