Search code examples
javastaticnullpointerexceptionjavac

Why does Java compiler allow static variable access through null object?


I was pointing some tricks and came across this. In following code:

public class TestClass1 {

    static int a = 10;

    public static void main(String ar[]){
        TestClass1 t1 = null ;
        System.out.println(t1.a); // At this line
    }
}

t1 object is null. Why this code is not throwing NullPointerException?

I know this is not proper way to access static variables but question is about NullPointerException.


Solution

  • To add some additional info to the current answers, if you disassemble your class file using:

    javap -c TestClass1
    

    You'll get:

    Compiled from "TestClass1.java"
    public class TestClass1 extends java.lang.Object{
    static int a;
    
    public TestClass1();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   return
    
    public static void main(java.lang.String[]);
      Code:
       0:   aconst_null
       1:   astore_1
       2:   getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       5:   aload_1
       6:   pop
       7:   getstatic   #3; //Field a:I
       10:  invokevirtual   #4; //Method java/io/PrintStream.println:(I)V
       13:  return
    
    static {};
      Code:
       0:   bipush  10
       2:   putstatic   #3; //Field a:I
       5:   return
    }
    

    Here you can see that the access to the static field is done in line 7 by the getstatc instruction. Whenever a static field is accessed through code, a corresponding getstatic instruction will be generated in the .class program file.

    *static instructions have the particularity that they don't requiere a reference to the object instance to be in the stack prior to calling them (like, for example invokevirtual which does require an object ref in the stack), they resolve the field/method using just an index to the run time constant pool that will be later used to solve the field reference location.

    That's a technical reason for the warning "The static field should be accessed in a static way" that some IDEs will throw at you when you write t1.a, because the object instance is unnecessary to resolve the static field.