是串连一个空string来做一个string转换真的很糟糕?
比方说,我有两个char
variables,后来我想将它们连接成一个string。 这是我将如何做到这一点:
char c1, c2; // ... String s = "" + c1 + c2;
我见过有人说"" +
“技巧”是“难看的”等等,而应该使用String.valueOf
或Character.toString
。 我更喜欢这个构造,因为:
- 如果可能,我更喜欢使用语言function而不是API调用
- 一般来说,不是比API更稳定的语言?
- 如果语言function只隐藏API调用,那么就更有理由更喜欢它了!
- 更抽象! 隐藏是好的!
- 我喜欢
c1
和c2
在视觉上处于同一水平-
String.valueOf(c1) + c2
暗示了c1
特殊之处
-
- 它更短。
为什么String.valueOf
或Character.toString
更适合于"" +
?
琐事:在java.lang.AssertionError
,下面一行出现7次,每次都有不同的types:
this("" + detailMessage);
你的论据很好, 这是Java语言中更具performance力的领域之一,正如你所发现的那样, "" +
成语似乎已经根深蒂固。
请参阅JLS中的string串联 。 一个expression式
"" + c1 + c2
相当于
new StringBuffer().append(new Character(c1).toString()) .append(new Character(c2).toString()).toString()
除了所有的中间对象不是必需的(所以效率不是动机)。 规范说实现可以使用StringBuffer
或不使用。 由于这个特性是内置在语言中的,我没有理由使用更冗长的forms,特别是在一个已经很冗长的语言中。
该构造的问题是它通常不expression意图。
它表示一个string与另一个值的连接,但是连接通常不是这一行的目标。
在您演示的特定情况下,连接实际上是目标,因此此代码确实expression了意图。
在这种方法( String s = "" + intValue;
)中比较常见的用法是,concatenation仅仅是一个容忍的副作用,而intValue
的转换是实际的目标。 而一个简单的String.valueOf(intValue)
表示意图更清晰。
我更喜欢使用String.valueOf
进行单次转换 – 但在你的情况下,你真的想要连接。
不过,我build议这个版本会消除所有可能的含糊之处:
String s = c1 + "" + c2;
那样的话,在连接之前不可能有人考虑是否将c1和c2加在一起。
在我看来, "" + x
是非常可读的,简短而精确的。 我更喜欢它像String.valueOf
更长的结构。 这个行为已经被很好地定义了,而且它的使用非常普遍,所以我觉得很难把它称为黑客。
唯一让我稍微担心的是性能 – 我非常肯定这通常不重要(即使我没有测量或查看二进制文件)。 还有一个公平的机会,这种concat是优化了,因为它应该很容易检测到(这只是一个猜测虽然)。
我认为在"" + var
实际上是重载进行转换:
Java语言为string连接运算符(+)提供特殊支持,并将其他对象转换为string。 string连接是通过StringBuilder(或StringBuffer)类及其附加方法实现的。 string转换通过toString方法实现,由Object定义并由Java中的所有类inheritance。 有关string连接和转换的更多信息
所以从技术angular度来说没有区别,也没有问题。
形成一个可读性的观点 – 这是一个个人喜好或团队内部认可的编码风格的问题。
关于什么
new String(new char[] {a, b})
如果你这样做了很多,你可以创build一个类“string”:
public static String valueOf(char... chars) { return new String(chars); }
然后你的行会被读取
String s = Strings.valueOf(a, b);
很好,很短。
编辑
一个更好的名字可能是:
String s = Chars.asString(a, b);
除非您的应用程序需要每盎司的性能,否则编写更快的代码,更易于阅读。 “”+是一个较慢的执行语法,但是每次使用它时,看起来似乎更容易阅读。
在我看来, "" + var
风格有一个非常大的问题。 它只是使用var
的toString方法。 所以如果你把var的types改成别的东西,你不会得到一个exception。 我刚刚遇到的一个很好的例子是types从int
更改为Optional<Integer>
。 该代码仍然编译好,但你得到一个完全不同的结果。
最好的方法是编译/反编译你的代码,我使用Jad http://en.wikipedia.org/wiki/JAD_(JAva_Decompiler ),你会看到你的expression式被转换成
String s =(new StringBuilder())。append(“”)。append(ci).append(c2).toString();
正如你所看到的,javac实际上包含了append(“”)调用,但是它的代价是微不足道的,注意到附加到内部的StringBuilder缓冲区,你可以检查StringBuilder的源代码