在 Java 中,使用 toString 方法与显式字符串转换与加引号(例如 myObj+"")有何区别?

In Java, what is the difference between using the toString method vs explicit String casting vs plus quotes (ex. myObj+"")?

加引号 (+"") 与使用 "toString()" 方法或什至使用 (String) myObject 之类的方法显式转换之间有什么区别?取舍?

myObject.toString()

对比

myObject+""

甚至对

(String) myObject

更具体地说,有没有什么时候使用 myObj+"" 方法会给您带来麻烦?

为清楚起见进行了编辑

编辑 2:

似乎 String.valueOf(myObj); 是避免空指针的首选方法。那就是说:有没有时候以下是错误的?

String.valueOf(myObj).equals(myObj+"")

从 Java 7 开始,如果您想避免 NullPointerException,您可以简单地使用以下之一:

Objects.toString( myObject )
Objects.toString( myObject, "defaultValueWhenMyObjectIsNull" )

在 Java 的所有版本中,第一个也可以通过以下方式完成,正如@NobuGames 在下面第一条评论中指出的那样:

String.valueOf( myObject )

您引用的机制各有缺陷。

 myObject.toString()  // throws NullPointerException if myObject is null.
 myObject+""          // Hack; impairs understandability.
 (String) myObject    // throws ClassCastException unless myObject is a String or null

编辑(问题编辑后)

is there any time using the myObj+"" method can get you into trouble?

是的,您可以混淆其他程序员。黑客的意图尚不清楚。这会导致时间成本增加,并增加某人 "fixing" 的风险。

但是,就编译器而言,您还可以。来自 Java Language Specification, section 15.18: String concatentation operator +:

If only one operand expression is of type String, then string conversion (§5.1.11) is performed on the other operand to produce a string at run time.

从引用的部分 5.1.11: String conversion

  • If the reference is null, it is converted to the string "null" (four ASCII characters n, u, l, l).

  • Otherwise, the conversion is performed as if by an invocation of the toString method of the referenced object with no arguments; but if the result of invoking the toString method is null, then the string "null" is used instead.

第二种情况导致了您所询问的差异。

Is there ever a time when the following is false? String.valueOf(myObj).equals(myObj+"")

不,但有时会抛出 NullPointerException。当 myObj 是对 toString() 方法 return 为空的对象的非空引用时,则 String.valueOf(myObj) 将为空。调用equals方法会抛出NullPointerException。

但我怀疑您是在问两者是否曾经有过不同的价值观。是的,它们可以有不同的值。 Objects.toString()String.valueOf() 可以 return 空值。 hack 将始终具有非空值。

就是说,从 toString() 中 returning null 有点不好。 JLS 承认它可能发生,但 API 暗示它不应该发生。就我个人而言,如果我担心这个案例,我会以黑客以外的其他方式处理它。

转换为字符串将高度依赖上下文,因此不止一种技术可以适用于此。如果您希望直接转换为 String,我的建议是做好准备。如果它有可能为空,则检查它。或者让 API 承诺不会给你一个 null。即,这是关注点的分离和责任的分层。

但是,IMO,任何足够复杂的 class 都应该有一个 toString() 方法。它可以用于调试,或用作 属性 进行计算,但它应该是人类可读的。根据我的经验,很少有不保证对象的人类可读版本的情况。

依靠重载 + 运算符 感觉 像 hack,是的。

此代码:

myObject+""

由编译器翻译为:

new StringBuilder().append(myObject).append("").toString()

StringBuilder 附加方法对输入参数进行空检查,附加文本 "null"。

Stringclass有一个重载的valueOf方法,所以你也可以这样做:

String.valueOf(myObject)

这将执行空检查,返回文本 "null"。