开发者

java static field from null [duplicate]

This question already has answers here: 开发者_JAVA百科 How come invoking a (static) method on a null reference doesn't throw NullPointerException? (5 answers) Closed 8 years ago.

I found this code on the Internet, and would love for someone to explain it to me...

public class Foo {
    static int fubar = 42;

    public static void main(String[] args) {
        System.out.println(((Foo) null).fubar);
    }
}

This code compiles and works correctly, outputting the result 42.

How is it possible that the variable fubar is accessed from a null without throwing a NullPointerException?


It's not actually looking for the field on null, because static methods and fields don't require an instance. The cast makes the type of the expression Foo, and fubar is a known static field on Foo, so the compiler and JVM have no issue.

Normally, you'd access the field by saying Foo.fubar. However, Java is nice enough to provide a shortcut: if you try to access a static field or method on an instance expression of a given type, it will treat it as if you had said [SomeType].theField. That's what's occurring here.


Because the field fubar is declared static, there is only one field anywhere actually named Foo.fubar. Each instance of Foo shares this one copy. When you access this field out of a Foo object, Java doesn't try following the object reference to find it. Instead, it looks up the object in a specially-defined location that can be accessed independently of any reference. Consequently, if you try looking up this field of the null object, you can do so without causing any sort of NullPointerException, since the object is never referenced.

EDIT: Bytecode is definitely in order! Given this source file:

public class Foo {
    static int fubar;
    public Foo() {
        ((Foo)null).fubar = 137;
    }
}

Here's the generated bytecode:

0:  aload_0
1:  invokespecial   #1; //Method Object."<init>":()V
4:  aconst_null
5:  checkcast   #2; //class Foo
8:  pop
9:  sipush  137
12: putstatic   #3; //Field fubar:I
15: return

Notice that line 12 uses the putstatic opcode, which stores a value into a static field. It doesn't reference a receiver object of any sort. In fact, if you'll notice, the generated bytecode (lines 4-8) does a cast of null to Foo, but then immediately issues a pop opcode to pop it off the stack. It's never referenced anywhere else in the bytecode.


fubar is a static member this cast of null just highlights the allocation of static variables at compile time rather than runtime. A much more common and equivalent way of accessing the static variable is this Foo.fubar

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜