我有一个关于用法的讨论String
S和StringBuffer
S IN的Java。 多少对象在每个这两个例子都是创造出来的?
例1:
String s = "a";
s = s + "b";
s = s + "c";
例2:
StringBuilder sb = new StringBuilder("a");
sb.append("b");
sb.append("c");
在我看来,例1将创建5和Ex 2将创建4个对象。
我有一个关于用法的讨论String
S和StringBuffer
S IN的Java。 多少对象在每个这两个例子都是创造出来的?
例1:
String s = "a";
s = s + "b";
s = s + "c";
例2:
StringBuilder sb = new StringBuilder("a");
sb.append("b");
sb.append("c");
在我看来,例1将创建5和Ex 2将创建4个对象。
您可以通过分析Java字节码(利用确定答案javap -c
)。 实施例1创建两个StringBuilder
对象(见行#4)和两个String
对象(见行#7),而实施例2创建一个StringBuilder
对象(见行#2)。
请注意,您还必须采取char[]
对象考虑(因为数组是在Java对象)。 String
和StringBuilder
对象使用底层两者实现char[]
因此,实施例1创建八个对象和实例2生成的两个对象。
实施例1:
public static void main(java.lang.String[]);
Code:
0: ldc #2; //String a
2: astore_1
3: new #3; //class java/lang/StringBuilder
6: dup
7: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V
10: aload_1
11: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
14: ldc #6; //String b
16: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22: astore_1
23: new #3; //class java/lang/StringBuilder
26: dup
27: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V
30: aload_1
31: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
34: ldc #8; //String c
36: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
39: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
42: astore_1
43: return
}
实施例2:
public static void main(java.lang.String[]);
Code:
0: new #2; //class java/lang/StringBuilder
3: dup
4: ldc #3; //String a
6: invokespecial #4; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
9: astore_1
10: aload_1
11: ldc #5; //String b
13: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
16: pop
17: aload_1
18: ldc #7; //String c
20: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
23: pop
24: return
}
我用了一个内存分析器得到确切的计数。
在我的机器,第一个例子创建了8个目标:
String s = "a";
s = s + "b";
s = s + "c";
String
; StringBuilder
; char[]
在另一方面,第二实施例:
StringBuffer sb = new StringBuffer("a");
sb.append("b");
sb.append("c");
创建2个对象:
StringBuilder
; char[]
这是使用JDK 1.6u30。
PS到了作出比较公平的,你可能应该调用sb.toString()
在第二个例子中结束。
在创建的对象的条件:
实施例1创建8个对象:
String s = "a"; // No object created
s = s + "b"; // 1 StringBuilder/StringBuffer + 1 String + 2 char[] (1 for SB and 1 for String)
s = s + "c"; // 1 StringBuilder/StringBuffer + 1 String + 2 char[] (1 for SB and 1 for String)
实施例2 2创建对象:
StringBuffer sb = new StringBuffer("a"); // 1 StringBuffer + 1 char[] (in SB)
sb.append("b"); // 0
sb.append("c"); // 0
为了公平起见,我不知道新的char []实际上在Java中创建一个对象(但我知道他们创建的)。 由于AIX指出了这一点。
答案是联系在一起的语言(编译器和运行库)的具体实现。 甚至到了特定优化选项或不存在。 而且,当然,执行的版本(并明确了JLS它符合)。 所以,最好的最小值和最大值的词来说话。 事实上,这项工作提供了一个更好的
对于练习1,对象的最小数目是1(编译器实现仅存在所涉及的常数以及用于仅产生代码String s= "abc" ;
最大的可能只是任何事情,这取决于实现,但一个合理的估计是8(在另一个答案,因为某些配置所产生的数量也给出)。
对于练习2,对象的最小数量是2的编译器没有办法知道,如果我们已经取代StringBuilder的具有不同语义的定制版本的方式,所以不会进行优化。 最大可能约为6,在极存储器节约的StringBuilder实现膨胀的背衬char[]
数组一次一个字符,但在大多数情况下,将2太。