I was just discussing about calling static methods using class name with my friend and tried out this code and expected it to throw NPE at runtime.but as it turn out it dint. i just want to understand the execution order.
public class One {
public static void method() {
System.out.println("in static one");
}
}
public class Two {
static One o;
public static void main(String[] args) {
o.method(); // expected NPE here, as o is null
}
}
I know that static methods should be invoked with their class name, I even know that IDE's would give a compiler warning when we call static methods with an instance. but we could also call them by creating an instance, however, i never created an instance here, o
should get its default value null, thus calling o.method()
should throw an NPE at run time, but it doesn't. can you guys please shed some light on how the execution order is in this code.
Because you declare
static One o;
outside themain
function. You can try to declare it inside themain
function, it cannot even be compiled...Or you can declare it as
One o = null
inmain
, then it will be compiled but it's the same asOne.method()
If you would have opened the code in your Development Environment e.g (Eclipse), instead of fooling people by showing the code here, which does provide code formating for static methods in italic style, then you would have seen that checkstyle claims about "Do not call a static method on an instance".
So it should be
instead of
Then it is clear why it does not crash!
method
is static so it doesn't care about theOne
instance.Is the same as:
It works because what matters is the compile-time type of the
o
field. The compiler will compileo.method()
into the same byte code asOne.method()
.In particular, if you had a class
Two
that extendsOne
, and both declare astatic void method()
, thenGood for obfuscation purposes, less good for maintainability...
static
methods or variables are associated with class definition itself and not with the class instance. Hence yourmethod()
is available ono
, but Ideally you should call it using the class name itself as: