String a = "abc";
String b = "xyz";
String result = a + b;
字符串存储器分配使用+运算
我想知道如果“结果”的字符串是在串池中字符串常量分配的内存或堆上创建一个新对象。
我知道新的字符串()上堆和字符串常量像创建对象,B在PermGen的串池空间上面的例子。
String a = "abc";
String b = "xyz";
String result = a + b;
字符串存储器分配使用+运算
我想知道如果“结果”的字符串是在串池中字符串常量分配的内存或堆上创建一个新对象。
我知道新的字符串()上堆和字符串常量像创建对象,B在PermGen的串池空间上面的例子。
的重要说明:
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.
换句话说,由于变量是'final',因此可以对其进行优化,并且Java编译器足够聪明,可以在编译时进行串联。 – Jesper 2012-08-15 14:15:31
正确,它是'javac'执行的少数优化之一。第一个示例可能会在每次运行时创建3-5个对象,第二个示例不会创建任何对象。 – 2012-08-15 14:19:53
了解。但看起来如果我想动态地使用a + b(不知道a和b的值),那么它确实创建了很多对象(由StringBuilder()创建),如果它在循环内部会更糟。 – 2012-08-15 14:32:04
如果编译和反编译代码,它会给下面的结果:
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
}
你可以看到在第10行的StringBuilder
分配串联字符串a
和b
。通知CONST1和CONST2的串联由编译器在线路25处理所以,如果你的字符串是final
它不会导致StringBuilder
分配
结果是什么==“abcxyz”return?这应该给你一个关于答案的暗示。 – Scorpion 2012-08-15 14:09:58