12

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.

Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361
PermGenError
  • 45,977
  • 8
  • 87
  • 106

5 Answers5

7

It works because what matters is the compile-time type of the o field. The compiler will compile o.method() into the same byte code as One.method().

In particular, if you had a class Two that extends One, and both declare a static void method(), then

One x = new Two();
x.method(); // calls One.method(), not Two.method()

Good for obfuscation purposes, less good for maintainability...

Ian Roberts
  • 120,891
  • 16
  • 170
  • 183
  • awesome, i got it now, iknew about static methods and how to call them, but just was confused when it dint throw NPE. so basically in bytecode, it would be One.method() eeven though we call thestatic method with an instace.. thanks ian again :) – PermGenError Dec 06 '12 at 21:15
  • @Ian - If is use `this.method()` instead of `o.method` Why don't the compiler compile it into `One.method()`? – Manoj May 18 '16 at 06:57
  • @Manoj I don't think the compiler would allow you to do `this.method()` in a static context. – Ian Roberts May 18 '16 at 12:41
  • 1
    @Manoj [JLS §15.8.3](https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.8.3) "The keyword `this` may be used only in the body of an instance method, instance initializer, or constructor, or in the initializer of an instance variable of a class. If it appears anywhere else, a compile-time error occurs." – Ian Roberts May 18 '16 at 12:47
6

method is static so it doesn't care about the One instance.

One o = null;
o.method();

Is the same as:

One.method();
Steve Kuo
  • 61,876
  • 75
  • 195
  • 257
0

static methods or variables are associated with class definition itself and not with the class instance. Hence your method() is available on o, but Ideally you should call it using the class name itself as:

     One.method();//static way of calling static methods
Yogendra Singh
  • 33,927
  • 6
  • 63
  • 73
  • as mentioned in the question, i know they should be called with classname.methodname(), but my queestion is why doesn't it throw NPE ?? could you give the reason ?? – PermGenError Dec 06 '12 at 21:09
  • @GanGnaMStYleOverFlowErroR: I answered in the bold. `static methods or variables are associated with class definition itself` and there is no class instance required for them. – Yogendra Singh Dec 06 '12 at 21:10
0

Because you declare static One o; outside the main function. You can try to declare it inside the main function, it cannot even be compiled...

Or you can declare it as One o = null in main, then it will be compiled but it's the same as One.method()

bhuang3
  • 3,493
  • 2
  • 17
  • 17
0

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

One.method()

instead of

o.method()

Then it is clear why it does not crash!

AlexWien
  • 28,470
  • 6
  • 53
  • 83
  • You probably need to read my complete question first. I know how to call a static method. My doubt was why was it not throwing NPE when o is null . Any who I got answer from Ian and also checked the code using byte code outline. It basically converts all the calls to static methods to class name . Method name. – PermGenError Dec 07 '12 at 18:26