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
Explicit vs implicit call of toString
提问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.valueOf
looks 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 "" + obj
method.
正如其他人所说 - 使用该"" + 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()
isnull
, 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