如果您在“效果问题”标题下启用所有检查,则会收到有关以下代码的警告(如标题中所示):
StringBuilder sb = new StringBuilder("Two");
String s = "One" + sb.toString();
我意识到toString()
是不必要的,但这是一个性能问题?
答案 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字符n
,u
,l
,{ {1}})。否则,转换的执行就好像通过调用引用对象的
l
方法而没有参数一样;但如果调用toString
方法的结果为toString
,则会改为使用字符串null
。
答案 1 :(得分:0)
这里有两件事:
“一个”+“两个”是最快的方法。它在运行时需要0纳秒(连接在编译时发生。)但IntelliJ并不足以构成连接。
它可能正在调用它,因为它是一个奇怪的事情,因为+如果你在循环中执行它可以生成大量对象,而StringBuilder是避免这个问题的一种方法。