据我所知,StringBuilder通过在concats期间不在字符串池中创建临时字符串实例来帮助减少内存使用量。 但是,如果我这样做会发生什么:
StringBuilder sb = new StringBuilder("bu");
sb.append("b"+"u");
是否编译成
sb.append("b");
sb.append("u");
?或者它取决于优化标志?或者,如果使用stringbuilders,我会失去整个好处? 或者这个排队没有意义? :)
答案 0 :(得分:8)
它编译为sb.append("bu")
,因为编译器将多个String litterals的串联转换为单个String litteral。
如果你有
String a = "a";
sb.append(a + "b");
它会把它编译成
String a = "a";
String temp = a + "b"; // useless creation of a string here
sb.append(temp);
所以你应该选择
sb.append(a);
sb.append("b");
在这种情况下。
答案 1 :(得分:7)
由于"b" + "u"
是一个在编译时计算的表达式,因此它将被编译为就像你有"bu"
一样。
0: new #2; //class StringBuilder
3: dup
4: ldc #3; //String bu
6: invokespecial #4; //Method StringBuilder."<init>":(String;)V
9: astore_1
10: aload_1
11: ldc #3; //String bu
13: invokevirtual #5; // StringBuilder.append:(String;)LStringBuilder;
另一方面,如果您有两个字符串变量,则此优化不会启动:
以下摘录......
StringBuilder sb = new StringBuilder("bu");
String b = "b", u = "u";
sb.append(b + u);
...编译为:
0: new #2; //class StringBuilder
3: dup
4: ldc #3; //String bu
6: invokespecial #4; //Method StringBuilder."<init>":(String;)V
9: astore_1
10: ldc #5; //String b
12: astore_2
13: ldc #6; //String u
15: astore_3
16: aload_1
17: new #2; //class StringBuilder
20: dup
21: invokespecial #7; //Method StringBuilder."<init>":()V
24: aload_2
25: invokevirtual #8; //Method StringBuilder.append:(String;)StringBuilder;
28: aload_3
29: invokevirtual #8; //Method StringBuilder.append:(String;)StringBuilder;
32: invokevirtual #9; //Method StringBuilder.toString:()String;
35: invokevirtual #8; //Method StringBuilder.append:(String;)StringBuilder;
即。与
相似的东西StringBuilder sb = new StringBuilder("bu");
String b = "b", u = "u";
StringBuilder temp = new StringBuilder();
temp.append(b);
temp.append(b);
String result = temp.toString();
sb.append(result);
正如您在第17-21行所示,我们创建了一个额外的StringBuilder
,用于连接a
和b
。然后,在第32行上获取此临时String
的结果StringBuilder
,并将其附加到第35行的原始StringBuilder
。
(字节码由javap
命令生成,该命令是JDK的一部分。试一试,它非常简单!)
答案 2 :(得分:0)
不,"b" + "u"
将创建一个不可变的b
字符串,一个不可变的u
字符串,然后创建第三个不可变的bu
字符串,并将其传递给{{ 1}}实例。
答案 3 :(得分:-1)
WRONG:
StringBuilder sb = new StringBuilder();
sb.append("b"+"u");
正确:
StringBuilder sb = new StringBuilder();
sb.append("b").append("u");
BEST://因为你已经知道那里会发生什么了! ;)
StringBuilder sb = new StringBuilder();
sb.append("bu");
:)
修改强>
我猜我上面的答案在处理文字时不正确......
:/