String objects and the heap
I am studying for the SCJP exam and I have a sample set of questions that I am working through.
One questions answer I am unsure about and was hoping someone here might be able to help me put this question to bed.
Here is the question,
Given:
11. public St开发者_开发技巧ring makinStrings() {
12. String s = "Fred";
13. s = s + "47";
14. s = s.substring(2, 5);
15. s = s.toUpperCase();
16. return s.toString();
17. }
How many String objects will be created when this method is invoked?
A. 1
B. 2
C. 3
D. 4
E. 5
F. 6
Thank you in advance for any help offered. I greatly appriciate it.
Let's go through it line by line.
Line 11
An easy start, no strings created here.
Line 12
We're assigning the String "Fred"
to s
. Although it looks like a String is created here, this string will live in the constant pool. The JVMS section 2.17.6 Creation of New Class Instances guarantees that the objects for string literals will at latest be created when the surrounding class is loaded, which by definition is before the method is invoked. So no new string objects are created on this line.
Line 13
The literal string "47"
is referenced, which again will have been created statically (as above). However there's also the invocation of the +
operator, which will create a new String in order to hold the result of the concatenation. So that's the first string created.
Line 14
The substring
method does indeed create a new String. It shares the underlying character array with its parent - and so takes up hardly any extra memory - but since Strings are immutable, each different string representation requires a different String
object. (This is probably a gotcha - my first instinctive response was "ah, string created by substring are special" but of course it still has to create a new object).
Line 15
As above - the uppercase representation is different, so a new String must be created to hold the result.
Line 16
Strings
override the toString()
method to simply return this
- hence no additional String is created.
The scores on the doors
By my count that's three String objects created during this method (with two of those objects sharing the same underlying character array, and with two pre-existing objects referenced for the string literals).
Actually, it would be possible to make the whole method into a single constant. It's possible, but the compiler isn't allowed to do so. Hence, there are 3 Strings created using 2 from the constant pool.
- Fred47
- ed4 (note: using same backing char[] as Fred47 though)
- ED4
2 and 3 are pretty easy as the compiler isn't allowed to optimize away this method invocations but the String is changed. Sting.toString() only returns this
, so no new String either. But let's have a look on line 13 using disassembled byte code (javap -c
is your friend here):
public java.lang.String makinStrings();
Code:
0: ldc #16; //String Fred
2: astore_1
3: new #18; //class java/lang/StringBuilder
6: dup
7: aload_1
8: invokestatic #20; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
11: invokespecial #26; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
14: ldc #29; //String 47
16: invokevirtual #31; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: invokevirtual #35; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
// SNIP
}
As you see, "Fred" and "47" are loaded from the constant pool (ldc
) to populate a StringBuilder that will finally become a String (StringBuilder.toString()).
So that makes 2 constant Strings plus 3 newly created Strings per method invocation.
I'd say 3: the ones at lines 12, 13 and 15.
The reason why the line 14 (substring) doesn't create a new object is because of the internal way String works. Due to necessary optimization of substring (everything, including compiler, rely on substring), the String class has two pointers to the start and end of the string. Doing a substring only moves this pointers, and does not "copy" the object into a new one.
it will create the 5 objects of string
string is immutable class so for every new string it will create an object.
example
- public String makinStrings() {
- String s = "Fred"; (this line create 1--- Fred string)
- s = s + "47"; (this line create 2- 47 string + 3- Fred47)
- s = s.substring(2, 5); (this line create 4-ed4)
- s = s.toUpperCase();(this line create 5-ED4)
- return s.toString();
So according to me it will create 5 object
精彩评论