它可能有助于向您显示字节码。请看一下类的以下输出: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
}
只要看一下主方法,你可以看到感兴趣的线在哪里是8和33。Code
代码 8 显示调用 的字节码。这里是,因此,对方法调用的任何尝试都会导致 .o.toString()
o
null
null
NullPointerException
代码 18 显示您的对象作为参数传递给方法。查看此方法的源代码将向您展示为什么这不会导致 NPE:null
PrintStream.print()
public void print(Object obj) {
write(String.valueOf(obj));
}
并将使用 s 执行此操作:String.valueOf()
null
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
所以你可以看到那里有一个测试来处理,并防止NPE。null