toString的显式vs隐式调用

时间:2008-11-30 09:23:29

标签: java tostring

当我想要一些关于对象的调试信息时,我常常使用toString的隐式调用,因为如果对象为null,则不会抛出异常。

例如:

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

而不是:

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

除了空案件之外是否有任何区别?
如果前者没有,后一种情况可以起作用吗?

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

5 个答案:

答案 0 :(得分:53)

没有什么区别。使用较短且工作频率较高的那个。

如果您确实想要出于其他原因获取对象的字符串值,并希望它为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;
}

所以......两种情况都会发生非常相似的事情。一个人只是做了一点工作。

答案 1 :(得分:3)

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

根据Java Language Spec

  • 如果该字词为空,请使用"null"
  • 使用盒装类型构造函数new Boolean(X)或其他
  • 转换原始类型
  • toString()被调用(或等效)
  • 如果toString()结果null,请使用"null"
  • 连接字符串。

答案 2 :(得分:1)

除了像你说的那样,零安全性没有区别。总是喜欢前者和后者。

答案 3 :(得分:1)

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

答案 4 :(得分: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