stringbuilder 调用中的 Java 字符串连接

发布于 2024-12-08 11:15:50 字数 293 浏览 0 评论 0原文

据我所知,StringBuilder 在连接期间不在字符串池中创建临时字符串实例,从而有助于减少内存使用量。 但是,如果我这样做会发生什么:

StringBuilder sb = new StringBuilder("bu");
sb.append("b"+"u");

它会编译成吗

sb.append("b");
sb.append("u");

?或者它取决于优化标志?或者我失去了弦乐建造者的全部好处? 或者这个问题没有意义? :)

As far as I know, StringBuilder helps to reduce memory usage by not creating temporary string instances in the string pool during concats.
But, what happens if I do sth like this:

StringBuilder sb = new StringBuilder("bu");
sb.append("b"+"u");

Does it compile into

sb.append("b");
sb.append("u");

? Or it depends on optimalization flags? Or I loose the whole benefit if stringbuilders?
Or this quetion makes no sense? :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

指尖上的星空 2024-12-15 11:15:51

不,"b" + "u" 将创建一个不可变的 b 字符串、一个不可变的 u 字符串,然后创建第三个不可变的 < code>bu 传递到 StringBuilder 实例的字符串。

No, the "b" + "u" will create an immutable b string, an immutable u string, and then create a third immutable bu string that gets passed into the StringBuilder instance.

平生欢 2024-12-15 11:15:51

错误:

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

正确:

StringBuilder sb = new StringBuilder();
sb.append("b").append("u");

最佳://因为你已经知道里面会有什么了! ;)

StringBuilder sb = new StringBuilder();
sb.append("bu");

:)

编辑

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

:/

WRONG:

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

CORRECT:

StringBuilder sb = new StringBuilder();
sb.append("b").append("u");

BEST: //Since you knew what's going to be in there already! ;)

StringBuilder sb = new StringBuilder();
sb.append("bu");

:)

EDIT

I guess my answer above is not correct when dealing with literals only...

:/

☆獨立☆ 2024-12-15 11:15:50

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

如果你有

String a = "a";
sb.append(a + "b");

它,会将其编译为

String a = "a";
String temp = a + "b"; // useless creation of a string here
sb.append(temp);

So 在这种情况下你应该更喜欢

sb.append(a);
sb.append("b");

It compiles to sb.append("bu"), because the compiler translates the concatenation of multiple String litterals to a single String litteral.

If you had

String a = "a";
sb.append(a + "b");

it would compile it to

String a = "a";
String temp = a + "b"; // useless creation of a string here
sb.append(temp);

So you should prefer

sb.append(a);
sb.append("b");

in this case.

十雾 2024-12-15 11:15:50

由于 "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 是为了连接 ab 而创建的。然后,在第 32 行获取此临时 StringBuilder 的结果 String,并将其附加到第 35 行的原始 StringBuilder


(字节码是由JDK 中的 javap 命令试试吧,非常简单!)

Since "b" + "u" is an expression which is evaluated at compile time, it will be compiled just as if you had "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;

If you on the other hand had two string variables, this optimization wouldn't kick in:

The following snippet...

StringBuilder sb = new StringBuilder("bu");
String b = "b", u = "u";

sb.append(b + u);

...gets compiled as:

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;

I.e. something similar to

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);

As you can see in line 17-21 an extra StringBuilder is created for the purpose of concatenating a and b. The resulting String of this temporary StringBuilder is then fetched on line 32 and appended to the original StringBuilder on line 35.


(The bytecode was generated by the javap command which is part of the JDK. Try it out, it's really simple!)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文