java - 以下创建了几个对象
PHP中文网
PHP中文网 2017-04-18 10:23:06
0
3
835

String a,b,c;
a = "a";
b = "b";
a = a+b;
StringBuffer d = new StringBuffer("abc");
d = d.append("567");

我觉得是6个,"a" "b" "ab" "abc" "567" 还有d.

PHP中文网
PHP中文网

认证0级讲师

reply all(3)
小葫芦

Tell me your understanding, and your feedback is welcome

  • a = "a"; When compiling, the string "a" is put into the constant pool and no object is created on the heap

  • b = "b"; Same reason

  • a = a + b; new a StringBuilder object, append(a), append(b), and finally return tostring() to a.

  • StringBuffer d = new StringBuffer("abc"); An object must be created here, and "abc" will enter the constant pool

  • d = d.append("567"); StringBuffer uses a char array to save the string. append will add "567" to the array. If the array capacity is not enough, it will be expanded. The default size is 16 + "abc" Length = 19, "abc567" has a length of 6, 3 + 3 < 19, so it will not cause expansion.

  • Another point is that StringBuffer and StringBuilder inherit AbstractStringBuilder, which may cause the creation of parent classes.

This is the decompiled code:

/**
 *
 * 源代码
 *public class TestString {
 *    public static void main(String args[]) {
 *        String a = "a";
 *        String b = "b";
 *        String c = a + b;
 *    }
 *}
 *
 */

Compiled from "TestString.java"
public class TestString {
    public TestString();
Code:
0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

       public static void main(java.lang.String[]);
Code:
       0: ldc           #2                  // String a
       2: astore_1
       3: ldc           #3                  // String b
       5: astore_2
       6: new           #4                  // class java/lang/StringBuilder
       9: dup
       10: invokespecial #5                  // Method java/lang/StringBuilder."<init>":()V
       13: aload_1
       14: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: aload_2
        18: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
24: astore_3
        25: return
}
迷茫

Let me tell you my answer first: I think it is 3.


First, let’s clarify the 创建对象 的具体含义. 按我的理解, 如果字符串是 字符常量, 那么这个字符串对象是在编译时候确定好的, 它是存放在常量池中的, 因此就不算是创建了一个字符串对象, 而如果有 String b = new String("abc") 之类的操作, 那么可以认为是创建了字符串对象, 并与变量 b association.

According to the above definition, then there are: "a", "b", "abc", "567" are all constants, placed in the constant pool, so they are not created as objects.

Let’s take a look at the code:
Source code:

1: String a,b,c;
2: a = "a";
3: b = "b";
4: a = a+b;
5: StringBuffer d = new StringBuffer("abc");
6: d = d.append("567");

For convenience, I numbered each line manually.
Let’s take a look at the corresponding bytecode:

Code:
  stack=3, locals=5, args_size=1
     0: ldc           #2                  // String a
     2: astore_1
     3: ldc           #3                  // String b
     5: astore_2
     6: new           #4                  // class java/lang/StringBuilder
     9: dup
    10: invokespecial #5                  // Method java/lang/StringBuilder."<init>":()V
    13: aload_1
    14: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    17: aload_2
    18: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    21: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
    24: astore_1
    25: new           #8                  // class java/lang/StringBuffer
    28: dup
    29: ldc           #9                  // String abc
    31: invokespecial #10                 // Method java/lang/StringBuffer."<init>":(Ljava/lang/String;)V
    34: astore        4
    36: aload         4
    38: ldc           #11                 // String 567
    40: invokevirtual #12                 // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
    43: astore        4
    45: return

As can be seen from the bytecode, the fourth line of the source code a = a+b is translated into the following code:

StringBuilder builder = new StringBuilder();
builder.append(a);
builder.append(b);
a = builder.toString();

Then a new object new StringBuilder(), 接着调用 builder.toString() method is created here, its source code is as follows:

@Override
public String toString() {
    // Create a copy, don't share the array
    return new String(value, 0, count);
}

So builder.toString() 方法创建了一个 String 对象, 因此目前我们已经创建了 两个对象.

Follow the fifth line StringBuffer d = new StringBuffer("abc") 毫无疑问是 创建了对象 StringBuffer, 于是我们就有 三个对象 了. 有一点需要注意的是 StringBuffer d 从始至终都没有调用 toString method, so no extra String will be created.


Summary:

  • "a": String constant, not counted as created object

  • "b": String constant, not counted as created object

  • builder object: Created when executing a = a+b.

  • "ab": Created by StringBuilder.toString().

  • "abc": String constant, not counted as created object

  • "567": String constant, not counted as created object

  • d: Created by new StringBuffer("abc").

So finally three objects are created.

阿神

Thank you for your answers. I probably understand it. Unfortunately, I can’t understand the decompiled code now

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template