Why does null reference print as “null”

折月煮酒 提交于 2019-12-17 04:33:05

问题


In println, here o.toString() throws NPE but o1, does not. 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
    }
}

回答1:


It might help showing you the bytecode. Take a look at the following javap output of your class:

> 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 shows the bytecode for you calling o.toString(). Here o is null and so any attempt on a method invocation on null results in a NullPointerException.

Code 18 shows your null object being passed as a parameter to the PrintStream.print() method. Looking at the source code for this method will show you why this does not result in the NPE:

public void print(Object obj) {
    write(String.valueOf(obj));
}

and String.valueOf() will do this with nulls:

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.




回答2:


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.

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.




回答3:


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)). String.valueOf(Object) doesn't throw the NPE like o.toString() does and is instead defined to return "null" for a null parameter.



来源:https://stackoverflow.com/questions/7374363/why-does-null-reference-print-as-null

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!