Reputation: 3120
How many String objects will the following code produce?
String s1="Hello"; //"Hello" is in String Pool Object #1
String s2 = s1.substring(2,3);//String object #2
String s3 = s1.toString();
String s4 = new StringBuffer(s1).toString(); //String Object #3
This is the question to one practice Java book I am reading. There is no answer, so I am not sure if my answer is right. Are there 3 or 5 string objects created? Does toString() create a new String object? I looked up online and found that toString() "Returns a string representation of the object". I don't quite understand what this means.
Upvotes: 0
Views: 1650
Reputation: 10667
It will create 3 String object. toString() method implementation of String class prints the content; it doesn't create any new object.
Upvotes: 0
Reputation: 3585
The answer to your question is implementation dependent, and misleading. There may be anywhere from 2 to 4 "String objects" by the end of the code fragment, exactly how many will depend on the JVM, and how aggressively it intern's small strings (if at all). As has been pointed out the JDK documentation specifies String.toString() return the object, so the answer should be "2 or 3"; however, you would be very foolish to rely on this behaviour.
The reason I say this is misleading is that you are never concerned about the "number of String objects". Objects in Java are very light weight, and you are never worried about counting them.
The only qualification I would add is that while you never care about object counts, you do care about references. In the case of Strings, a nasty surprise can be the number of references to the underlying char array. String objects are flyweights that share the char array, and forgetting this can lead to severe memory leaks. A very simple way to exhaust the heap on a java program is to:
while(!multiGBFileEOF) {
String bigString = readMultiMBString();
int index = findSmallFeature(bigString);
String featureOfInterest = bigString.substring(index, index+4);
featureList.add(featureOfInterest);
}
The featureList should end up being at most a few 10KB's (~1000 list items each * (4-8 bytes for the arrayref + 12-20 bytes for the object + 8-16 bytes for the char array), ie trivial. However because some common JVM implementations share the backing array for Strings generated by substring(), this could end up trying to store the entire file in memory. The solution is to force an explicit copy of the underlying array by calling String copy = new String(featureOfInterest)
. Here you don't care if copy
and featureOfInterest
are the same object or not, as long as copy
does not alias the char array behind bigString
.
Good luck with your learning.
Upvotes: 0
Reputation: 5183
Whenever you use a new keyword to create a string object it will create a new String object no matter the string is already present in the pool of strings
String s1="Hello"; //this will create a new string object and add it to the pool of strings
String s2 = s1.substring(2,3);//String object #2 again creates a string and adds it in the pools of strings
String s3 = s1.toString();//this will not create a new object but simply refer to already existing object in the pool of strings
String s4 = new StringBuffer(s1).toString(); //String Object #3 this will create a new object as you are using new keyword
an example
public class Main {
public static void main(String[] args) {
String s1 = "abc";//created a string and added it to pool of string
String s2 = "abc";//no need to create a new object
String s3 = new String("abc");
System.out.println("s1 = " + s1);
System.out.println("s2 = " + s2);
System.out.println("s2 = " + s3);
System.out.println("s1 == s2? " + (s1 == s2));//proves that the ref refer to same object
System.out.println("s1 == s3?"+ (s1==s3));
System.out.println("s1.equals(s2)? " + (s1.equals(s2)));
}
}
the output
s1 = abc
s2 = abc
s3 = abc
s1 == s2? true
s1 == s3? false
s1.equals(s2)? true
Upvotes: 3
Reputation: 183290
It will create three. Your analysis is correct.
Does toString() create a new String object? I looked up online and found that toString() "Returns a string representation of the object".
That's the description for the generic Object.toString
, but String
overrides it to give more specific behavior. Its version is documented this way:
This object (which is already a string!) is itself returned.
[link]
Upvotes: 7
Reputation: 66637
I think you are correct. Number of String objects would be 3 NOT 5.
s1.toString();
javadoc says:
This object (which is already a string!) is itself returned.
new StringBuffer(s1)
creates new String object.
Upvotes: 4