以下简单的代码片段工作正常,并且正在访问带有null对象的静态字段。
final class TestNull
{
public static int field=100;
public TestNull temp()
{
return(null);
}
}
public class Main
{
public static void main(String[] args)
{
System.out.println(new TestNull().temp().field);
}
}
在上面的代码中,静态字段 字段 的语句System.out.println(new TestNull().temp().field);
与NULL对象new TestNull().temp()
相关联,仍然是正在返回 100 的正确值,而不是在Java中抛出空指针异常!为什么呢?
答案 0 :(得分:12)
与常规成员变量相反,静态变量属于类,而不属于类的实例。它的工作原因仅仅是因为你不需要需要一个实例才能访问静态字段。
事实上,如果访问静态字段可能会抛出NullPointerException
,我会说更令人惊讶。
如果你很好奇,这里是字节码查找你的程序:
// Create TestNull object
3: new #3; //class TestNull
6: dup
7: invokespecial #4; //Method TestNull."<init>":()V
// Invoke the temp method
10: invokevirtual #5; //Method TestNull.temp:()LTestNull;
// Discard the result of the call to temp.
13: pop
// Load the content of the static field.
14: getstatic #6; //Field TestNull.field:I
Java Language Specification, Section 15.11.1: Field Access Using a Primary中对此进行了描述。他们甚至提供了一个例子:
以下示例演示一个空引用可用于访问类(静态)变量而不会导致异常:
class Test { static String mountain = "Chocorua"; static Test favorite(){ System.out.print("Mount "); return null; } public static void main(String[] args) { System.out.println(favorite().mountain); } }
它编译,执行和打印:
Mount Chocorua
答案 1 :(得分:5)
静态变量在类的每个对象之间共享。因此,当您返回的实际对象引用为null时(在C ++中:TestNull * temp = null;),您有一个TestNull类型的对象,Java可以使用它来查找该类的静态值。
记住Java对象真的是指针。指针有一种类型。从那种类型,Java可以识别某些信息,即使它指向null。
答案 2 :(得分:3)
静态字段与该类关联,而不是该类的实例。因此,您不需要对象的实例来访问静态字段。
您也可以通过调用TestNull.field
来访问该字段