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
}
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:
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
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:
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:
For convenience, I numbered each line manually.
Let’s take a look at the corresponding bytecode:
As can be seen from the bytecode, the fourth line of the source code
a = a+b
is translated into the following code:Then a new object
new StringBuilder()
, 接着调用builder.toString()
method is created here, its source code is as follows: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