连接字符串和使用StringBuffer之间的区别

时间:2011-02-22 09:17:11

标签: java string localization internationalization stringbuilder

静态内容已在Java文件中进行了硬编码,如下所示:

String s = "<span class=\"className\">StaticContent</span>";

必须使用ResourceBundle对象进行外部化。

一种简单的方法是:

String s = "<span class=\"className\">" + 
           ResourceBundleObject.getString("StaticContent.key") + "</span>";

第二种方法是使用StringBuilder对象:

StringBuilder sb = new StringBuilder();
sb.append("<span class=\"className\">");
sb.append(ResourceBundleObject.getString("StaticContent.key"));
sb.append("</span>");
String s = sb.toString();

第二种方法是否优于第一种方法(就消耗的资源而言)?

使用第一种方法更容易,因为它涉及的编辑非常少。

5 个答案:

答案 0 :(得分:4)

Strings的一个串联创建一个新的String对象:

"a" + "b" + "c" + "d"      // 4 Strings
"ab"                       // 1 String
"abc"                      // 1 String
"abcd"                     // 1 String
                           // 7 String instances in total (& in theory / worst case)

StringBuilder创建的对象更少:

StringBuilder sb = new StringBuilder("a").append("b").append("c").append("d")
                           // 4 Strings, 1 StringBuilder 
                               = 5 objects (in theory/worst case)

但是编译器意识到了这个问题,如果你看一下类文件的字节代码,通常就会看到字符串连接已被StringBuilder替换并追加。考虑到这一点,您可以专注于可读代码,并将其留给编译器以找到最高性能的解决方案。

就个人而言,如果我必须组装大型字符串(如java源代码或html页面)或者使用循环来组装字符串,我只使用专用的StringBuilder,如下所示:

 String result = "";
 for (int i = 0; i < 100; i++)
   result += ".";    // Ouch - this should be done with StringBuilder

答案 1 :(得分:2)

在这种情况下,使用显式StringBuilder没有性能优势。

JLS表示允许Java编译器将一系列字符串连接子表达式编译为临时StringBuilderappend调用序列的等效创建。在这种情况下,优化工作,并且编译器将生成与您自己使用StringBuilder时获得的字节码有效相同的字节码。换句话说,使用StringBuilder的唯一净效果是使您的代码更难阅读。

如果您的代码在循环中进行连接,则只能通过显式使用StringBuilder来获得性能优势。但是,如果以这种方式构建长字符串,性能差异可能很大。

答案 2 :(得分:1)

 1. First One will create three Instance.  // "" will create 2 temp instance , concat using + another instance 
 2. Second One wil create One Instance.

 - the String class is an immutable class.
 - It will never really change internally. When you use the operator
   it actually  do not change the string itself, but rather return a
   new String.

 - StringBuilder is more efficient as it is designed with no thread-safety in mind.
 - Will appends to it the previous value of the string.
 - if you are building long strings, then using StringBuilder
 - no synchronization is performed.
 - StringBuilder lacks some methods split,search

答案 3 :(得分:1)

字符串是不可变的 - 一旦创建它们就无法修改。

因此,如果你执行string1 + string2,string2不仅仅被复制到string1的末尾 - 创建一个包含连接字符串的新字符串。如果你完成这些操作的整个序列,它将变得非常昂贵。

你应该注意,但是,在有些情况下,JVM将字符串cncatenation代码(使用+)转换为stringbuilder调用序列。所以实际上你的两个片段应该编译成smae(或非常相似)的字节码。

与以往一样,如果您想获得最佳性能,请进行测试和测量。

答案 4 :(得分:0)

第二种方法与第一种方法相比具有明显的优势,因为在第一种情况下我们使用new运算符创建一个新的字符串对象是不可变的但是在String Builder的情况下,顾名思义我们将附加到原始字符串,从而我们没有创建额外的新String对象,因此在String Buiilder.String Builder的情况下保存内存也是可变的。