Java 用空字符串连接来进行字符串转换真的那么糟糕吗?
假设我有两个Java 用空字符串连接来进行字符串转换真的那么糟糕吗?,java,string,coding-style,Java,String,Coding Style,假设我有两个char变量,稍后我想将它们连接成一个字符串。我会这样做: char c1, c2; // ... String s = "" + c1 + c2; 我见过一些人说“+”把戏“很难看”,等等,你应该用String.valueOf或Character.toString来代替。我更喜欢这种结构,因为: 如果可能的话,我更喜欢使用语言特性而不是API调用 一般来说,这种语言不是比API更稳定吗 若语言特性只隐藏API调用,那个么更强烈的理由是更喜欢它! 更抽象!躲起来很好 我
char
变量,稍后我想将它们连接成一个字符串。我会这样做:
char c1, c2;
// ...
String s = "" + c1 + c2;
我见过一些人说“+
”把戏“很难看”,等等,你应该用String.valueOf
或Character.toString
来代替。我更喜欢这种结构,因为:
- 如果可能的话,我更喜欢使用语言特性而不是API调用
- 一般来说,这种语言不是比API更稳定吗
- 若语言特性只隐藏API调用,那个么更强烈的理由是更喜欢它!
- 更抽象!躲起来很好李>
- 我喜欢
和c1
在视觉上处于同一水平c2
表明String.valueOf(c1)+c2
c1
- 它比较短
String.valueOf
或Character.toString
比“”+
更可取,真的有一个好的参数吗
琐事:在中,以下行出现7次,每次都有不同的类型:
this("" + detailMessage);
我认为在“+var
中,+
实际上是重载的,以进行转换:
Java语言为字符串连接运算符(+)以及其他对象到字符串的转换提供了特殊支持。字符串连接是通过StringBuilder(或StringBuffer)类及其append方法实现的。字符串转换是通过toString方法实现的,该方法由Object定义并由Java中的所有类继承。有关字符串连接和转换的更多信息,请参见
因此,从技术角度来看,没有区别,也没有问题
形成可读性的观点-这是个人偏好或团队内部一致同意的编码风格的问题。你的论点很好;这是Java语言更具表现力的领域之一,正如您所发现的,
“+
习惯用法似乎根深蒂固
请参阅JLS中的。像这样的表情
"" + c1 + c2
相当于
new StringBuffer().append(new Character(c1).toString())
.append(new Character(c2).toString()).toString()
除了不需要所有的中间对象(因此效率不是动机)。该规范规定,实现可以使用
StringBuffer
,也可以不使用。由于该功能内置于该语言中,因此我认为没有理由使用更详细的形式,尤其是在已经非常详细的语言中。该结构的问题在于它通常无法表达意图
它表示字符串与另一个值的连接,但连接通常不是此行的目标
在您演示的特定案例中,串联实际上是目标,因此此代码确实表达了意图
在这种方法的更常见用法(String s=“”+intValue;
)中,浓缩只是一种可容忍的副作用,而intValue
的转换是实际目标。一个简单的String.valueOf(intValue)
更清楚地表达了这个意图。在我看来,“+x
非常可读、简短、精确。我更喜欢它,而不是像String.valueOf
这样的较长结构。这种行为定义明确,而且使用非常普遍,我觉得很难称之为黑客行为
我唯一有点担心的是性能——我非常肯定这通常并不重要(尽管我没有测量或查看二进制文件)。这种concat也很有可能被优化掉,因为它应该很容易检测到(不过这只是一个猜测)。除非你的应用程序需要每一盎司的性能,否则请编写写起来更快、更容易阅读的代码。“+”是一种执行速度较慢的语法,但每次我使用它时,它看起来确实更容易阅读。怎么办
new String(new char[] {a, b})
如果您经常这样做,您可以创建一个类“Strings”,其中包含:
你的台词是
String s = Strings.valueOf(a, b);
又好又短
已编辑
更好的名称可能是:
String s = Chars.asString(a, b);
我更喜欢对单个转换使用
String.valueOf
,但在您的情况下,您确实需要串联
但是,我建议该版本将消除所有潜在的歧义:
String s = c1 + "" + c2;
通过这种方式,无论多么遥远,都不可能有人考虑在连接之前是否将c1和c2添加到一起。最好的方法是编译/反编译代码,我使用Jad)为此,您将看到表达式已转换为 字符串s=(新的StringBuilder()).append(“”).append(ci).append(c2).toString()
正如您所看到的,javac实际上包含了append(“”)调用,但它的成本可以忽略不计,因为它被附加到了内部StringBuilder缓冲区中,您可以检查StringBuilder的源代码,
“+var
样式在我看来有一个非常大的问题。它只使用var
的toString方法。因此,如果将var的类型更改为其他类型,则不会出现异常。我刚刚遇到的一个很好的例子是,类型从int
更改为Optional
。代码仍然可以编译,但得到的结果完全不同。我刚刚在问题中添加了[coding style]标记;这就是主要的原因,我不这么认为<代码>“”+x非常常见,其意图应该是清楚的。@mafurtct:如果意图只有在您以前多次看到该确切构造时才清楚,那么它本身就不清楚。这只能证明模式识别是有效的。@polygene:够公平的了@克里斯:让我试着重新表述一下你的论点:“这并不难看,因为它很普遍。”这听起来不对。@克里斯:那么我误读了你的评论,对不起。但是这是否意味着应该使用它呢?如果你的代码在一个循环中运行了数十万次,这一点非常重要。没有人会在一个循环中使用它——你总是在循环中使用它
String s = c1 + "" + c2;