Intellij警告“串联中的StringBuffer.toString()”

时间:2015-12-04 14:35:02

标签: java string intellij-idea stringbuilder intellij-14

如果您在“效果问题”标题下启用所有检查,则会收到有关以下代码的警告(如标题中所示):

StringBuilder sb = new StringBuilder("Two");
String s = "One" + sb.toString();

我意识到toString()是不必要的,但这是一个性能问题?

2 个答案:

答案 0 :(得分:5)

如果您要使用字符串连接运算符(StringBuilder),使用+没有意义,这会在幕后创建StringBuilder,从而导致创建两个StringBuilder个对象而不是一个。您只需重复使用StringBuilder来连接字符串:

StringBuilder sb = new StringBuilder("One");
sb.append("Two");
String s = sb.toString();

原始代码相当于:

StringBuilder sb = new StringBuilder("Two");
StringBuilder sb2 = new StringBuilder("One");
String s = sb2.append(sb.toString()).toString();

与警告相关的另一个方面(诚然与性能相关而不是代码优化)是toString()在与+操作数一起使用时是多余的。这是因为编译器会自动调用toString()。这是您在问题中已经猜到的内容,并在Java语言规范中进行了解释:

(来自https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.18.1):

  

如果只有一个操作数表达式是String类型,则在另一个操作数上执行字符串转换(第5.1.11节)以在运行时生成字符串。

其中section 5.1.11说:

  
      
  • 如果引用为null,则会将其转换为字符串"null"(四个ASCII字符nul,{ {1}})。

  •   
  • 否则,转换的执行就好像通过调用引用对象的l方法而没有参数一样;但如果调用toString方法的结果为toString,则会改为使用字符串null

  •   

答案 1 :(得分:0)

这里有两件事:

  1. “一个”+“两个”是最快的方法。它在运行时需要0纳秒(连接在编译时发生。)但IntelliJ并不足以构成连接。

  2. 它可能正在调用它,因为它是一个奇怪的事情,因为+如果你在循环中执行它可以生成大量对象,而StringBuilder是避免这个问题的一种方法。