我们必须一直为日志输出构建字符串等等。在JDK版本中,我们已经学习了什么时候使用StringBuffer(许多追加,线程安全)和StringBuilder(许多追加,非线程安全)。

使用String.format()有什么建议?它是有效的,还是我们被迫坚持在性能很重要的一行程序中使用连接?

例如,丑陋的老式风格,

String s = "What do you get if you multiply " + varSix + " by " + varNine + "?";

vs.整洁的新样式(字符串。格式,可能更慢),

String s = String.format("What do you get if you multiply %d by %d?", varSix, varNine);

注意:我的特定用例是代码中的数百个“一行”日志字符串。它们不涉及循环,所以StringBuilder太重量级了。我对String.format()特别感兴趣。


当前回答

To expand/correct on the first answer above, it's not translation that String.format would help with, actually. What String.format will help with is when you're printing a date/time (or a numeric format, etc), where there are localization(l10n) differences (ie, some countries will print 04Feb2009 and others will print Feb042009). With translation, you're just talking about moving any externalizable strings (like error messages and what-not) into a property bundle so that you can use the right bundle for the right language, using ResourceBundle and MessageFormat. Looking at all the above, I'd say that performance-wise, String.format vs. plain concatenation comes down to what you prefer. If you prefer looking at calls to .format over concatenation, then by all means, go with that. After all, code is read a lot more than it's written.

其他回答

考虑使用“hello”。Concat(“世界!”)对于连接的少量字符串。它甚至比其他方法的性能更好。

如果你有超过3个字符串,考虑使用StringBuilder,或者只使用String,这取决于你使用的编译器。

你的旧样式会被JAVAC 1.6自动编译为:

StringBuilder sb = new StringBuilder("What do you get if you multiply ");
sb.append(varSix);
sb.append(" by ");
sb.append(varNine);
sb.append("?");
String s =  sb.toString();

所以这和使用StringBuilder是没有区别的。

字符串。format要重量级得多,因为它创建了一个新的Formatter,解析输入格式字符串,创建一个StringBuilder,将所有内容附加到它并调用toString()。

通常应该使用String。格式,因为它相对较快,并且支持全球化(假设您实际上正在尝试编写用户可以阅读的内容)。如果您试图翻译一个字符串,而不是每个语句翻译3个或更多字符串(特别是对于语法结构截然不同的语言),它还可以使全球化变得更容易。

现在,如果您不打算翻译任何东西,那么要么依赖于Java内置的+运算符到StringBuilder的转换。或者显式地使用Java的StringBuilder。

这个问题的答案在很大程度上取决于您特定的Java编译器如何优化它生成的字节码。字符串是不可变的,理论上,每个“+”操作都可以创建一个新的字符串。但是,你的编译器几乎肯定会优化掉构建长字符串的中间步骤。上面的两行代码完全有可能生成完全相同的字节码。

唯一真正了解的方法是在当前环境中迭代地测试代码。编写一个QD应用程序,以迭代的方式连接字符串,并查看它们如何彼此超时。

在您的示例中,性能可能没有太大不同,但还有其他问题需要考虑:即内存碎片。连接操作也在创建一个新字符串,即使它是临时的(GC需要时间,而且工作量更大)。String.format()可读性更强,涉及的碎片更少。

此外,如果你经常使用特定的格式,不要忘记你可以直接使用Formatter()类(所有String.format()所做的是实例化一个使用Formatter实例)。

此外,还应该注意其他一些事情:小心使用substring()。例如:

String getSmallString() {
  String largeString = // load from file; say 2M in size
  return largeString.substring(100, 300);
}

这个大字符串仍然在内存中,因为这就是Java子字符串的工作方式。一个更好的版本是:

  return new String(largeString.substring(100, 300));

or

  return String.format("%s", largeString.substring(100, 300));

如果你同时做其他事情,第二种形式可能更有用。