是否与空字符串连接进行字符串转换真的那么糟糕?

时间:2010-03-24 09:23:05

标签: java string coding-style

假设我有两个char变量,后来我想将它们连接成一个字符串。我就是这样做的:

char c1, c2;
// ...

String s = "" + c1 + c2;

我见过有人说"" +“技巧”“丑陋”等等,你应该使用String.valueOfCharacter.toString代替。我更喜欢这种结构,因为:

  • 如果可能,我更喜欢使用语言功能而不是API调用
    • 一般来说,语言通常不比API更稳定吗?
    • 如果语言功能只隐藏API调用,那么更有理由更喜欢它!
      • 更抽象!隐藏很好!
  • 我喜欢c1c2在视觉上处于同一级别
    • String.valueOf(c1) + c2建议c1
    • 有些特别之处
  • 它更短。

为什么String.valueOfCharacter.toString更喜欢"" +,真的有一个很好的论据吗?


琐事:在java.lang.AssertionError中,以下行出现7次,每次都有不同的类型:

    this("" + detailMessage);

9 个答案:

答案 0 :(得分:25)

你的论点很好;这是Java语言中比较具有表现力的领域之一,"" +成语似乎根深蒂固,正如您所发现的那样。

请参阅JLS中的String concatenation。像

这样的表达式
"" + c1 + c2

相当于

new StringBuffer().append(new Character(c1).toString())
                  .append(new Character(c2).toString()).toString()

除了不需要所有中间对象(因此效率不是动机)。规范说实现可以使用StringBuffer或不使用{{1}}。由于此功能已内置于该语言中,因此我认为没有理由使用更详细的表单,尤其是在已经详细的语言中。

答案 1 :(得分:19)

该构造的问题在于它通常不表达意图。

它表示String与另一个值的串联,但连接通常不是此行的目标。

在您演示的特定情况下,连接实际上是目标,因此此代码 表达意图。

在这种方法(String s = "" + intValue;)的更常见用法中,连词只是一种容忍的副作用,而intValue的转换是实际目标。一个简单的String.valueOf(intValue)表达了更清晰的意图。

答案 2 :(得分:4)

我更喜欢将String.valueOf用于单个转换 - 但在您的情况下,您确实需要连接。

但是,我建议这个版本将消除所有潜在的歧义:

String s = c1 + "" + c2;

这样就不会有人考虑在串联之前是否将c1和c2加在一起。

答案 3 :(得分:2)

我认为在"" + var中,+实际上已经超载以进行转换:

  

Java语言为字符串连接运算符(+)提供特殊支持,并为其他对象转换为字符串。字符串连接是通过StringBuilder(或StringBuffer)类及其append方法实现的。字符串转换是通过方法toString实现的,由Object定义并由Java中的所有类继承。有关字符串连接和转换的其他信息

从技术角度来看,没有区别也没有问题。

形成一个可读性的观点 - 这是团队中个人偏好或商定的编码风格的问题。

答案 4 :(得分:2)

在我看来,"" + x非常易读,简短,准确。我更喜欢它用于String.valueOf这样的较长构造。这个行为定义得很好,并且在使用中如此常见,以至于我发现很难将其称为hack。

我唯一担心的是性能 - 而且非常积极的是它通常并不重要(即使我没有测量或查看二进制文件)。这种concat也很有可能被优化掉,因为它应该很容易被发现(这只是猜测)。

答案 5 :(得分:2)

怎么样?
new String(new char[] {a, b})

如果你这么做,你可以用:

创建一个“Strings”类
public static String valueOf(char... chars) {
    return new String(chars);
}

然后您的行将会读取

String s = Strings.valueOf(a, b);

好又短。

<强>被修改

更好的名字可能是:

String s = Chars.asString(a, b);

答案 6 :(得分:1)

除非您的应用需要每一盎司的性能,否则请编写更快速编写且更易于阅读的代码。 “”+是一种执行速度较慢的语法,但每次使用它时看起来肯定更容易阅读。

答案 7 :(得分:1)

"" + var风格在我看来有一个很大的问题。它只使用var的toString方法。因此,如果将var的类型更改为其他类型,则不会出现异常。我刚刚遇到的一个很好的例子是类型已从int更改为Optional<Integer>。代码仍然编译得很好,但是你会得到完全不同的结果。

答案 8 :(得分:0)

最好的方法是编译/反编译你的代码,我使用了Jad http://en.wikipedia.org/wiki/JAD_(JAva_Decompiler),你会看到你的表达式被转换为

String s =(new StringBuilder())。append(&#34;&#34;)。append(ci).append(c2).toString();

正如您所看到的,javac实际上包含了append(&#34;&#34;)调用,但其成本可以忽略不计,注意事项是附加到内部StringBuilder缓冲区,您可以查看StringBuilder的源代码