This question already has an answer here:
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
.
To add some additional info to the current answers, if you disassemble your class file using:
You'll get:
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 correspondinggetstatic
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.What is the reason of
NullPointerException
in a code like that:If SomeMethod is an instance method it'll do something with standard this reference:
Since this is null we'll have NullPointerException. If method, field etc. is static it's guaranteed the absense of this reference, so there'll be no
NullPointerException
There is no need for an instance while invoking static member or method.
Since static members belongs to class rather than instance.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#d5e19846
If you see the example (see full example in spec)
Since
a
is static compiler converts it toTestClass1.a
. For non-static variables it would throwNullPointerException
.t1.a
is equivalent toTestClass1.a
in this case, sincea
is a static member (not an instance member). The compiler looks at the declaration oft1
to see what type it is, and then just treats it as if you had used the type name. The value oft1
is never checked. (But if it were a method call, likemethod(args).a
, I think the method would be called. But the return value would be thrown away, and never checked.) (Edit: I've verified thatmethod(args)
is called, but no exception is thrown if the function result is null.)Any Static member can be accessed by Directly class name as TestClass1.a no need of instance for it
output: 10