在Java中使用String.format
和字符串拼接之间有明显的区别吗?
我倾向于使用String.format
,但偶尔会用拼接。我想知道哪一个更好。
我认为,String.format
在“格式化”字符串方面给您更多的控制权;而拼接意味着您不必担心意外地输入额外的%s或漏掉一个。
String.format
也更短。
哪个更易读取取决于您的思维方式。
在Java中使用String.format
和字符串拼接之间有明显的区别吗?
我倾向于使用String.format
,但偶尔会用拼接。我想知道哪一个更好。
我认为,String.format
在“格式化”字符串方面给您更多的控制权;而拼接意味着您不必担心意外地输入额外的%s或漏掉一个。
String.format
也更短。
哪个更易读取取决于您的思维方式。
然而,连接功能不太实用且难以阅读。与往常一样,值得在代码上进行基准测试以查看哪种方法更好。在资源包、语言环境等加载到内存中并且代码被JIT编译后,服务器应用程序中的差异可能微不足道。
也许作为最佳实践,如果您需要进行大量格式化,则最好使用自己的Formatter,其中包含正确大小的StringBuilder(Appendable)和Locale。
可能会有明显的差异。
String.format
非常复杂,并在底层使用正则表达式,因此不要习惯性地到处使用它,而是只在需要时使用。
StringBuilder
将快上一个数量级(如这里已经指出的)。
MessageFormat.format
,因为它在可读性和性能方面都很好。我使用了与在他上面的答案中使用的相同程序,并附加了使用MessageFormat
的代码,以解释性能数字。 public static void main(String[] args) {
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = "Hi " + i + "; Hi to you " + i * 2;
}
long end = System.currentTimeMillis();
System.out.println("Concatenation = " + ((end - start)) + " millisecond");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = String.format("Hi %s; Hi to you %s", i, +i * 2);
}
end = System.currentTimeMillis();
System.out.println("Format = " + ((end - start)) + " millisecond");
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String s = MessageFormat.format("Hi %s; Hi to you %s", i, +i * 2);
}
end = System.currentTimeMillis();
System.out.println("MessageFormat = " + ((end - start)) + " millisecond");
}
连接 = 69 毫秒
格式化 = 1435 毫秒
MessageFormat = 200 毫秒
更新:
根据SonarLint报告,应正确使用Printf样式格式字符串(squid:S3457)。
由于printf-style
格式字符串是在运行时解释的,而不是由编译器验证的,它们可能包含错误,导致创建错误的字符串。当调用java.util.Formatter
、java.lang.String
、java.io.PrintStream
、MessageFormat
和java.io.PrintWriter
类的format(...)方法以及java.io.PrintStream
或java.io.PrintWriter
类的printf(...)
方法时,此规则静态验证printf-style
格式字符串与其参数之间的相关性。
我将printf-style替换为花括号,并得到以下有趣的结果。
连接时间 = 69 毫秒
格式化时间 = 1107 毫秒
使用大括号的格式化时间 = 416 毫秒
MessageFormat = 215 毫秒
使用大括号的MessageFormat时间 = 2517 毫秒
我的结论:
如上所述,使用带有大括号的String.format应该是一个不错的选择,既能获得良好的可读性,又能获得良好的性能。
要熟悉String.Format需要一些时间,但在大多数情况下它是值得的。在“永不重复任何东西”的世界中,使用常量库(我更喜欢静态类)保持令牌化的消息(日志或用户)非常有用,并在必要时调用它们,无论您是否进行本地化。尝试使用连接方法的库更难阅读、调试、校对和管理,而使用任何需要连接的方法都是如此。替换是一个选择,但我怀疑它的性能。经过多年的使用,我对String.Format最大的问题是当我将其传递到另一个函数(例如Msg)中时,其长度很不方便,但这很容易通过自定义函数作为别名来解决。
你不能通过上面的程序比较字符串拼接和字符串格式化。
你可以尝试在代码块中交换使用String.Format和拼接的位置,如下所示:
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
for( int i=0;i<1000000; i++){
String s = String.format( "Hi %s; Hi to you %s",i, + i*2);
}
long end = System.currentTimeMillis();
System.out.println("Format = " + ((end - start)) + " millisecond");
start = System.currentTimeMillis();
for( int i=0;i<1000000; i++){
String s = "Hi " + i + "; Hi to you " + i*2;
}
end = System.currentTimeMillis();
System.out.println("Concatenation = " + ((end - start)) + " millisecond") ;
}