假设我有两个char
变量,后来我想将它们连接成一个字符串。我就是这样做的:
char c1, c2;
// ...
String s = "" + c1 + c2;
我见过有人说"" +
“技巧”“丑陋”等等,你应该使用String.valueOf
或Character.toString
代替。我更喜欢这种结构,因为:
c1
和c2
在视觉上处于同一级别
String.valueOf(c1) + c2
建议c1
为什么String.valueOf
或Character.toString
更喜欢"" +
,真的有一个很好的论据吗?
琐事:在java.lang.AssertionError
中,以下行出现7次,每次都有不同的类型:
this("" + detailMessage);
答案 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的源代码