toString 的显式调用与隐式调用

发布于 2024-07-09 10:11:41 字数 315 浏览 8 评论 0原文

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

例如:

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

而不是:

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

除了 null 情况之外还有什么区别吗?
当前一种情况不行时,后一种情况可以吗?

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

I used to use the implicit call of toString when wanting some debug info about an object, because in case of the object is null it does not throw an Exception.

For instance:

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

instead of:

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

Is there any difference apart from the null case?
Can the latter case work, when the former does not?

Edit:
What exactly is done, in case of the implicit call?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

向地狱狂奔 2024-07-16 10:11:41

差别不大。 使用较短且更有效的方法。

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

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

There's little difference. Use the one that's shorter and works more often.

If you actually want to get the string value of an object for other reasons, and want it to be null friendly, do this:

String s = String.valueOf(obj);

Edit: The question was extended, so I'll extend my answer.

In both cases, they compile to something like the following:

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

When your toString() is implicit, you'll see that in the second append.

If you look at the source code to java, you'll see that StringBuilder.append(Object) looks like this:

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

where String.valueOf looks like this:

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

Now, if you toString() yourself, you bypass a null check and a stack frame and go straight to this in StringBuilder:

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

So...very similar things happens in both cases. One just does a little more work.

我一直都在从未离去 2024-07-16 10:11:41

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

根据 Java 语言规范

  • 如果该术语为 null,则使用 "null"
  • 使用装箱类型构造函数 new Boolean(X) 或任何
  • toString() 调用(或等效)code>
  • 转换原始类型如果 toString()结果null,则
  • ,请使用 "null"连接字符串。

As others have said - use the "" + obj method.

According to The Java Language Spec:

  • If the term is null, use "null"
  • Primitive types are converted using the boxed-type constructor new Boolean(X) or whatever
  • toString() is invoked (or equivalent)
  • if the result of toString() is null, use "null"
  • Concatenate the strings.
同展鸳鸯锦 2024-07-16 10:11:41

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

No difference except, like you say, the null safety. Always prefer the former to the latter.

沦落红尘 2024-07-16 10:11:41

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

Actually, if your invariant says the object should never be null, it doesn't matter. So it depends on whether or not you accept obj to be null.

少女的英雄梦 2024-07-16 10:11:41

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

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

It is quite easy to write a generic reference type.

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);
  }
}

Running it gives the required output:

javac ref.java && java ref
foo
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文