什么时候应该显式使用StringBuilder?

据我了解,当我执行String baz = "foo" + "bar" + "123" ,Java编译器在内部用StringBuilder替换表达式。 但是我们的Java老师告诉我们,总是明确地使用StringBuilder是个好习惯…

我是否正确假设我需要在连接内部循环时显式使用StringBuilder,如Stack Overflow问题字符串生成器与字符串连接的答案中所示? 是否还有其他情况需要显式使用StringBuilder而不是++=

它比“内部循环”更通用 – 它是您想要在多个语句上进行连接的任何时候,并且不需要将中间结果作为字符串。 例如:

 StringBuilder builder = new StringBuilder("Start"); if (someCondition) { builder.append("Foo"); } if (someOtherCondition) { builder.append("Bar"); } builder.append("End"); String result = builder.toString(); 

虽然你可以这样写:

 String result = "Start" + (someCondition ? "Foo" : "") + (someOtherCondition ? "Bar" : "") + "End"; 

……变得难以阅读。 如果if体内有更多的陈述,甚至可能都不可行。

要纠正问题中的某些内容:

据我了解,当我执行String baz =“foo”+“bar”+“123”时,java编译器在内部用StringBuilder替换表达式。

不,当您编写该表达式时,编译器会识别出它是编译时常量,并将其替换为

 String baz = "foobar123"; 

这是明确使用StringBuilder的一个很好的理由 – 上面的代码在执行时显然比效率更高

 String baz = new StringBuilder("foo").append("bar").append("123").toString(); 

当它不是编译时常量时,Java编译器将使用StringBuilder执行连接,通常使用比使用StringBuilder更容易理解的代码,但没有性能损失。 我怀疑你的老师要么没有正确理解字符串连接,要么只是在其他地方读取你应该使用StringBuilder而不完全理解它是否合适。

欧比万说,只有西斯认为绝对或类似的东西……

很高兴您知道Java编译器在内部使用StringBuilder替换了Strings上的“+”。 这就是编译器:使生活更轻松。

除非你有循环,如链接的情况,或Jon Skeet的例子中的条件,它主要是可读性和维护的容易性。

更换

 return "User " + userName + " said"; 

 new StringBuilder().append("User ").append(userName).append(" said").toString(); 

使代码更长,可能更难修改,更有可能强制换行,并为您提供更多性能。

但是,当添加不仅适用于字符串,而且涉及数字时,可能使用StringBuilder的解决方案有时可能更具可读性。

 return "User" + a + b + " said: " + (c + d); 

可能更令人困惑的是:

 return new StringBuilder().append("User ").append(a).append(b) .append(" said: ").append(c+d).toString(); 

但这主要是意见和编码风格的问题。 “应该”在这里不是一个好词。

它们也适用于使用String实现C#的’out’关键字之类的东西。 例

 public int getInt(StringBuilder error) { int retVal = 0; if (someErrorOccured) error.append("Couldn't get int because of..."); else retVal = whatItsSupposedToBe; return retVal; }