Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
stringbuilder调用中的Java字符串concat_Java_String_Stringbuilder - Fatal编程技术网

stringbuilder调用中的Java字符串concat

stringbuilder调用中的Java字符串concat,java,string,stringbuilder,Java,String,Stringbuilder,据我所知,StringBuilder通过在concats期间不在字符串池中创建临时字符串实例来帮助减少内存使用。 但是,如果我这样做会发生什么: StringBuilder sb = new StringBuilder("bu"); sb.append("b"+"u"); 它编译成 sb.append("b"); sb.append("u"); ??还是取决于优化标志?或者我失去了所有的利益,如果我的话? 还是这个问题毫无意义?:) 它编译为sb.append(“bu”),因为编译器将多个字

据我所知,StringBuilder通过在concats期间不在字符串池中创建临时字符串实例来帮助减少内存使用。 但是,如果我这样做会发生什么:

StringBuilder sb = new StringBuilder("bu");
sb.append("b"+"u");
它编译成

sb.append("b");
sb.append("u");
??还是取决于优化标志?或者我失去了所有的利益,如果我的话?
还是这个问题毫无意义?:)

它编译为sb.append(“bu”),因为编译器将多个字符串literal的串联转换为单个字符串literal

如果你有

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");
在本例中。

否,
“b”+“u”
将创建一个不可变的
b
字符串,一个不可变的
u
字符串,然后创建第三个不可变的
bu
字符串,该字符串将被传递到
StringBuilder
实例中

错误:

StringBuilder sb = new StringBuilder();
sb.append("b"+"u");
正确:

StringBuilder sb = new StringBuilder();
sb.append("b").append("u");
贝斯特://既然你已经知道里面会有什么!;)

:)

编辑

我想我上面的答案在处理文字时是不正确的

:/

由于
“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: 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;
如第17-21行所示,创建了一个额外的
StringBuilder
,用于连接
a
b
。然后在第32行提取该临时
StringBuilder
的结果
String
,并将其附加到第35行的原始
StringBuilder



(字节码是由JDK中的
javap
命令生成的。试试看,它非常简单!)

这对Java来说是比较新的吗?我一直认为字符串串联会导致多个字符串,因为它们是不可变的?或者这只适用于连接字符串变量吗?不,这不是新的。能够正确格式化(在几行上)长字符串文字非常有用,例如长SQL或JPQL查询。对于第二个代码示例,不仅将创建一个字符串,还将创建一个额外的StringBuilder。@jbniset:Given
string cd=“cd”,如何优化以下字符串<代码>字符串abcdef=“a”+“b”+cd+“e”+“f”??谢谢实际上,“错误”的版本等同于“最佳”版本。请参阅@aioobe的答案。@StephenC:您知道编译器如何/如果/为什么优化以下内容:`String abcde=“a”+“b”+c+“d”+“e”@Gevorg-我知道它是这样的,因为JLS说它是这样的,如果编译器没有这样做,那么它就不是一个有效的Java编译器。不,它不会。请看@aioobe的答案。我不能相信编译器不够聪明,不能不创建单字母文字,或者,如果没有那么多的否定,我相信编译器足够聪明,只能创建
bu
字符串。@CarlosHeuberger-这不是“聪明”。这只是一个实现Java语言规范的问题。@Stephen-可以理解为:开发和实现编译器的人足够聪明…@CarlosHeuberger-阅读和实现规范是你对smart的定义吗?不过,公平地说,规范很有可能反映了第一个编译器,而不是相反。你猜到了我真正想问的问题:)所以当我只有文本时,就会发生优化,对于变量,总是使用append。@aioobe:Given
String cd=“cd”,以下两个是否也是等效的<代码>字符串abcdef=“a”+“b”+cd+“e”+“f”字符串abcdef=“ab”+cd+“ef”`?谢谢@Gevorg,我想是的,为什么不用
javap
?:-)试试呢哈哈,不是。只需执行
javac测试。java
然后执行
javap-c测试
@aioobe:我做到了,太棒了!:)它编译成
“ab”+cd+“e”+“f”我也尝试了不同的输入,基本上只有变量优化前的文本。非常有趣。。我想这可能与“+”的自然顺序有关。。
 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);