[英]Why does null reference print as “null”
In println, here o.toString() throws NPE but o1, does not. 在println中,这里o.toString()抛出NPE但是o1抛出NPE。 Why? 为什么?
public class RefTest {
public static void main(String[] args) {
Object o = null;
Object o1 = null;
System.out.println(o.toString()); //throws NPE
System.out.print(o1); // does not throw NPE
}
}
It might help showing you the bytecode. 它可能有助于向您显示字节码。 Take a look at the following javap
output of your class: 看一下你班级的以下javap
输出:
> javap -classpath target\test-classes -c RefTest
Compiled from "RefTest.java"
public class RefTest extends java.lang.Object{
public RefTest();
Code:
0: aload_0
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: aconst_null
1: astore_1
2: aconst_null
3: astore_2
4: getstatic #17; //Field java/lang/System.out:Ljava/io/PrintStream;
7: aload_1
8: invokevirtual #23; //Method java/lang/Object.toString:()Ljava/lang/String;
11: invokevirtual #27; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
14: getstatic #17; //Field java/lang/System.out:Ljava/io/PrintStream;
17: aload_2
18: invokevirtual #33; //Method java/io/PrintStream.print:(Ljava/lang/Object;)V
21: return
}
Just looking at the main method, you can see the lines of interest are where Code
is 8 and 33. 只需查看主要方法,您就可以看到感兴趣的行是Code
为8和33的位置。
Code 8 shows the bytecode for you calling o.toString()
. 代码8显示了调用o.toString()
的字节码。 Here o
is null
and so any attempt on a method invocation on null
results in a NullPointerException
. 这里的o
为null
,因此对null
的方法调用的任何尝试都会导致NullPointerException
。
Code 18 shows your null
object being passed as a parameter to the PrintStream.print()
method. 代码18显示了您的null
对象作为参数传递给PrintStream.print()
方法。 Looking at the source code for this method will show you why this does not result in the NPE: 看着这个方法会告诉你为什么,这并不在NPE导致的源代码:
public void print(Object obj) {
write(String.valueOf(obj));
}
and String.valueOf()
will do this with null
s: 和String.valueOf()
将使用null
s执行此操作:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
So you can see there is a test there which deals with null
, and prevents an NPE. 所以你可以看到有一个测试处理null
,并阻止NPE。
It's because print(Object)
uses String.valueOf(Object)
for the conversion (aside: after the conversion println(Object)
would behave as though print(String)
was called, print(Object)
effectively uses write(int)
). 这是因为print(Object)
使用String.valueOf(Object)
进行转换(除了:转换后println(Object)
就像调用print(String)
, print(Object)
有效地使用write(int)
)。 String.valueOf(Object)
doesn't throw the NPE like o.toString()
does and is instead defined to return "null"
for a null parameter. String.valueOf(Object)
不像o.toString()
那样抛出NPE,而是定义为null参数返回"null"
。
System.out.println(o.toString())
o.toString()
is trying to dereference a null object to convert it to a string, before passing it to println
. o.toString()
尝试取消引用null对象以将其转换为字符串,然后再将其传递给println
。
System.out.print(o1);
The print
being called is the print(Object)
variant, which is itself checking that the object is not null before proceeding. 该print
被称为是print(Object)
的变体,这本身就是检查的对象不是继续之前空。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.