在Java中使用NULL对象访问静态字段

时间:2011-11-07 20:19:52

标签: java

以下简单的代码片段工作正常,并且正在访问带有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中抛出空指针异常!为什么呢?

3 个答案:

答案 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

来访问该字段