本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看 活动链接
Debug 笔记 <Java中的字符串连接-何时使用+,StringBuilder和concat>
提问
什么时候我们应该使用+来串接字符串,何时首选StringBuilder以及什么时候适合使用concat。
我听说StringBuilder更适合在循环内进行串联。
为什么会这样呢?
回答一:
我倾向于StringBuilder在关注性能的代码路径上使用。循环内重复的字符串连接通常是一个不错的选择。
喜欢的理由StringBuilder是,无论+和concat创建新的对象每次调用时(提供的右手边参数不为空)。这可以快速添加很多对象,几乎完全不需要所有对象。
正如其他人指出的那样,当+在同一条语句中多次使用时,编译器通常可以为您优化此过程。但是,以我的经验,当串联发生在单独的语句中时,该参数不适用。它肯定对循环没有帮助。
综上所述,我认为当务之急是编写清晰的代码。有一些很棒的Java分析工具(我使用YourKit),可以很容易地查明性能瓶颈并仅在重要的地方进行优化。
PS我从来不需要使用concat。
回答二:
现代Java编译器通过StringBuilder的附录来转换您的+操作。
我的意思是说,如果这样做str = str1 + str2 + str3,编译器将生成以下代码:
StringBuilder sb = new StringBuilder();
str = sb.append(str1).append(str2).append(str3).toString();
您可以使用DJ或Cavaj来反编译代码以确认这一点:因此,现在使用+或StringBuilder而不是提高性能,
更多的是选择问题:
但是,考虑到编译器无法为您完成的情况(如果您使用任何私有Java SDK进行操作,则可能会发生),那么肯定可以使用StringBuilder,因为这样可以避免大量不必要的String对象。
回答三:
String是不可变的:您不能修改String对象,但可以通过创建新实例来替换它。
//Inefficient version using immutable String
String output = "Some text";
int count = 100;
for (int i = 0; i < count; i++) {
output += i;
}
return output;
上面的代码将构建99个新String对象,其中98个将立即被丢弃。创建新对象效率不高。
StringBuffer易变:使用StringBuffer或StringBuilder要修改内容时使用。StringBuilder是在Java 5中添加的,并且在所有方面都相同,StringBuffer除了它不同步之外,这使其以不具有线程安全性为代价而稍快一些。
//More efficient version using mutable StringBuffer
StringBuffer output = new StringBuffer(110);
output.append("Some text");
for (int i = 0; i < count; i++) {
output.append(i);
}
return output.toString();
上面的代码仅创建两个新对象,即返回StringBuffer的最终对象String。StringBuffer可以根据需要进行扩展,但这很昂贵,因此最好StringBuffer从一开始就使用正确的大小来初始化。
回答四:
+:在连接2个或3个字符串时使用,只是为了使代码简短易读。StringBuilder:在构建复杂的String输出或需要关注性能的情况下使用。String.format:您没有在问题中提到这一点,但是它是我创建Strings的首选方法,因为在我看来,它使代码最易读/简洁,并且对于日志语句特别有用。concat:我认为我没有理由使用它。
回答五:
如果所有串联的元素都是常量
(例如:)"these" + "are" + "constants",
那么我更喜欢+,因为编译器会为您内联串联。否则,使用StringBuilder是最有效的方法。
如果将+与非常量一起使用,则编译器还将在内部使用StringBuilder,但由于所使用的代码与源代码不再相同,因此调试变得很麻烦。
文章翻译自Stack Overflow :stackoverflow.com/questions/7…