43

在需要有关对象的一些调试信息时,我曾经使用 toString 的隐式调用,因为如果对象为空,它不会抛出异常。

例如:

System.out.println("obj: "+obj);

代替:

System.out.println("obj: "+obj.toString());

除了 null case 有什么不同吗?
后一种情况可以工作,而前一种情况不行吗?

编辑:
在隐式调用的情况下到底做了什么?

4

5 回答 5

59

差别不大。使用更短且工作更频繁的那个。

如果您出于其他原因实际上想要获取对象的字符串值,并且希望它对 null 友好,请执行以下操作:

String s = String.valueOf(obj);

编辑:问题已扩展,所以我将扩展我的答案。

在这两种情况下,它们都会编译成如下内容:

System.out.println(new StringBuilder().append("obj: ").append(obj).toString());

当你toString()是隐式的时,你会在第二个追加中看到。

如果您查看 java 的源代码,您会看到StringBuilder.append(Object)如下所示:

public StringBuilder append(Object obj) {
    return append(String.valueOf(obj));
}

String.valueOf看起来像这样:

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

现在,如果你toString()自己,你绕过空检查和堆栈帧,直接进入StringBuilder

public StringBuilder append(String str) {
    super.append(str);
    return this;
}

所以......在这两种情况下都会发生非常相似的事情。一个只是做更多的工作。

于 2008-11-30T09:26:18.443 回答
3

正如其他人所说 - 使用该"" + obj方法。

根据Java 语言规范

  • 如果术语为空,请使用"null"
  • new Boolean(X)使用盒装类型构造函数或其他任何东西转换原始类型
  • toString()被调用(或等效)
  • 如果结果toString()null使用"null"
  • 连接字符串。
于 2008-11-30T09:41:28.383 回答
1

没有区别,就像你说的,零安全。总是更喜欢前者而不是后者。

于 2008-11-30T09:25:53.233 回答
1

实际上,如果你的不变量说对象永远不应该为空,那没关系。所以这取决于你是否接受 obj 为空。

于 2008-11-30T11:04:08.107 回答
0

编写泛型引用类型非常容易。

class ref
{
  static public class Reference<T>
  {
    private T value;
    public Reference(T value) { set(value); }
    public Reference() { set(null); }
    public void set (T value) { this.value = value; }
    public T get () { return this.value; }
    public String toString() { return String.valueOf(this.value); }
  }

  static void fillString (Reference<String> str)
  {
    str.set("foo");
  }

  public static void main (String[] args)
  {
    Reference<String> str = new Reference<String>("");
    fillString(str);
    System.out.println (str);
  }
}

运行它会给出所需的输出:

javac ref.java && java ref
foo
于 2013-07-16T13:09:19.057 回答