【问题标题】:Primitive + "" versus Wrapper.toString(primitive)Primitive + "" 与 Wrapper.toString(primitive)
【发布时间】:2012-12-25 01:10:20
【问题描述】:

当需要将原语转换为字符串时,例如传递给需要字符串的方法,基本上有两种选择。

int为例,给出:

int i;

我们可以做以下之一:

someStringMethod(Integer.toString(i));
someStringMethod(i + "");

第一个是“正式”的方法,第二个似乎有点“hack”。

它的代码肯定少了很多,并且更容易阅读“hack”恕我直言。
但是使用“hack”是“好的”编码风格吗?

【问题讨论】:

  • 我不会将第二个版本描述为更易于阅读。
  • 我同意第二个不是真的更容易阅读,而且它当然不包含少得多的代码。也许更少的字符,但我几乎可以保证它会生成更多的字节码。
  • @D.Shawley 你是对的,我记得""+something 在反编译时会生成类似(new StringBuffer("")).append(String.valueOf(something).toString() 的东西,或者类似的丑陋的东西。

标签: java coding-style


【解决方案1】:

将 * 转换为 String 的最佳方法是使用:

String.valueOf(x)

它适用于实现toString() 的原始类型、包装类和对象。

其中 x 是任何类型的基元或对象。如果为 null,则返回字符串 'null'。

之所以最好,是因为使用“+”操作数意味着字符串连接,加上“”意味着字符串实例化。如果您使用 ""+something 反编译一个类,您会看到编译器将其转换为多个操作。

"" 连接结果与String.valueOf() 相同,但要贵一些。 性能差异可能可以忽略不计,但是优秀的程序员不会在有更好的方法时编写'"" + something'来将某些内容转换为String,这恰好是正确的方法:)。

对于数组,请查看 Arrays.toString() 和 -better- Arrays.deepToString()

但是使用“hack”是“好的”编码风格吗?

有时语法 hack 会使代码变得更好。但是上面的案例并不是真正的案例之一。 "" 连接不是好的代码。

一个有用的句法技巧的例子是双括号实例化:

List<String> list = new ArrayList<String>() {{
    add("foo");
    add("bar");
    add("baz");
}};

而不是

List<String> list = new ArrayList<String>();
list.add("foo");
list.add("bar");
list.add("baz");

""+something 更像是一种代码味道,而不是提高可读性的 hack;任何有经验的人都会想到一个缺乏 API 和语言知识的 Java 开发人员。

其他有趣的“hacks”是流畅的 API(如 Mockito)、dsl 或 lambda4j 之类的东西,这真是一个 hack。

【讨论】:

  • +1 - valueOf 和类似的操作几乎总是比隐式强制更适合 null 的情况。
  • 我喜欢 String.valueOf()。老实说,我忘记了这一点
【解决方案2】:

这不是一个好主意,但不会造成太大的危害。

在这两个示例中,Integer.toString() 都被 JVM 调用(即使在第一种情况下不是直接调用)。

在第二个示例中,JVM 可能会构造两个字符串,然后生成连接的结果。根据优化,这可能会导致 0、1 或 2 个额外的字符串被垃圾收集。

从代码编写的角度来看,第三个更短,但对于正在发生的事情也可能不太透明。

第二种方法在可读性方面的问题如下:

int i = 1, j = 2;
someStringMethod(i + j + "" + i + j + "");

生产:

someStringMethod(312);

而不是

someStringMethod(33);

【讨论】:

  • 我不太确定在这两种情况下都调用了Integer.toString()javap 表明 appender 方法调用 StringBuilder.append 两次 - 一次使用整数参数和字符串参数。大多数现代 Java 实现在很久以前就停止使用字符串连接了。
  • 我们在这里谈论的是编程风格,而不是效率。连接几乎肯定会被编译器优化掉。在任何情况下,您都必须分析您的代码以了解它是否真的有所作为。但无论如何,出于样式原因,请使用 .toString 或 StringBuilder。
  • 我举了一个例子,说明由于 + 运算符的多次使用而导致不清楚的情况。不过老实说,CheckStyle 并没有抱怨任何一种方法,所以这没什么大不了的......感谢@D.Shawley 的更正
【解决方案3】:

当使用+号形成字符串时,jvm会创建一个中间的string/stringbuffer对象来进行转换,这不是最优的方式。 此外,+ 符号是左关联的,所以当在像 ""+1+2 这样的表达式中使用时,结果是 12 而不是 "3"。所以最好使用 String.toValue() 或 Type。字符串()。

【讨论】:

  • 其实是String.valueOf() 不是String.toValue(),但你的答案是正确的。来自我的 +1 :)
【解决方案4】:

java中的连接符号是+。 因此,您将 (i + "") 的结果转换为字符串,因为您在示例代码中将一个空字符串连接到一个数字。
这两种方式都不错,但我通常使用String.valueOf(x);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-21
    • 1970-01-01
    • 2016-04-17
    • 1970-01-01
    • 2015-09-08
    • 1970-01-01
    相关资源
    最近更新 更多