String a = "abc";
String b = "xyz";
String result = a + b;
我想知道“结果”字符串是字符串池中分配的字符串常量内存还是在堆上创建的新对象。
我知道 new String() 在 permgen 字符串池空间中的上述示例中创建堆上的对象和字符串常量,如 a,b。
String a = "abc";
String b = "xyz";
String result = a + b;
我想知道“结果”字符串是字符串池中分配的字符串常量内存还是在堆上创建的新对象。
我知道 new String() 在 permgen 字符串池空间中的上述示例中创建堆上的对象和字符串常量,如 a,b。
重要说明:
String a = "abc";
String b = "xyz";
String result = a + b;
是相同的
// creates a number of objects.
String result = new StringBuilder().append(a).append(b).toString();
但
final String a = "abc";
final String b = "xyz";
String result = a + b;
是相同的
String result = "abcxyz"; // creates no new objects.
如果你编译和反编译你的代码,它会给出以下结果:
String result = new StringBuilder().append(a).append(b).toString();
连接导致分配一个 StringBuilder 来创建连接的字符串。
来源:
public class Hello {
public static final String CONST1 = "cafe";
public static final String CONST2 = "babe";
public static void main(String[] args){
String a = "abc";
String b = "xyz";
String result = a + b;
String result2 = CONST1 + CONST2;
}
}
通过 javap 反汇编:
public class Hello extends java.lang.Object{
public static final java.lang.String CONST1;
public static final java.lang.String CONST2;
public Hello();
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 abc
2: astore_1
3: ldc #3; //String xyz
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: ldc #8; //String cafebabe
27: astore 4
29: return
}
您可以StringBuilder
在第 10 行看到用于连接 Stringa
和b
. 注意 CONST1 和 CONST2 的连接由编译器在第 25 行处理。所以如果你的字符串是final
它不会导致StringBuilder
分配