Java toString 的显式与隐式调用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/328661/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 13:31:00  来源:igfitidea点击:

Explicit vs implicit call of toString

javatostring

提问by Burkhard

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.

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

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?

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

采纳答案by Dustin

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.

当您toString()是隐式时,您将在第二个附加中看到它。

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

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

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

where String.valueOflooks like this:

其中,String.valueOf如下所示:

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:

现在,如果你toString()自己,你绕过空检查和堆栈帧并直接进入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.

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

回答by cletus

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

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

回答by Draemon

As others have said - use the "" + objmethod.

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

According to The Java Language Spec:

根据Java 语言规范

  • 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 resultof toString()is null, use "null"
  • Concatenate the strings.
  • 如果该术语为空,则使用 "null"
  • 原始类型使用盒装类型构造函数new Boolean(X)或其他方法进行转换
  • toString()被调用(或等效的)
  • 如果结果toString()null,使用"null"
  • 连接字符串。

回答by P?l GD

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.

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

回答by ceving

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