开发者

String objects and the heap

开发者 https://www.devze.com 2023-04-10 18:26 出处:网络
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 q

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

  1. public String makinStrings() {
    1. String s = "Fred"; (this line create 1--- Fred string)
    2. s = s + "47"; (this line create 2- 47 string + 3- Fred47)
    3. s = s.substring(2, 5); (this line create 4-ed4)
    4. s = s.toUpperCase();(this line create 5-ED4)
    5. return s.toString();

So according to me it will create 5 object

0

精彩评论

暂无评论...
验证码 换一张
取 消