Why does null reference print as “null”

前端 未结 3 1004
傲寒
傲寒 2020-11-27 06:36

In println, here o.toString() throws NPE but o1, does not. Why?

public class RefTest {
    public static void main(String[] args) {
        Object o = null;
         


        
3条回答
  •  执笔经年
    2020-11-27 07:04

    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."":()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.

提交回复
热议问题