6

Why is it possible to get access to the static method of my super class from child instance?

public class Test {

    public static void main(String[] args) {
        new UtilImpl().fun();
        new AbstractUtil() {}.fun();
    }

    static abstract class AbstractUtil {
        public static void fun() {
            System.out.println("Fun!");
        }
    }

    static class UtilImpl extends AbstractUtil {
    }

}

I can agree with access to the static method of parent class from an instance of the parent class. But if I instantiate a child class, it's weird to have access to the static context of the parent class.

PS

And what are advantages of calling the static method on instance?

Finkelson
  • 2,921
  • 4
  • 31
  • 49
  • 3
    Why ? Because it is specified this way. However, you will get a warning. – Dici Sep 05 '15 at 20:51
  • This topic is very well covered, with examples and explanations, here: https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html – Sva.Mu Sep 05 '15 at 20:57
  • The question is actually not uninteresting, check the SO question I linked – Dici Sep 05 '15 at 20:58

2 Answers2

5

In Java, it is allowed to call static methods with an instance variable. This is defined in JLS section 8.4.3.2, quoting:

A method that is declared static is called a class method.

A class method is always invoked without reference to a particular object.

In such a case, Java will actually discard the instance you used and call the static method.

Example 15.12.4.1-1 expresses this in the following way:

When a target reference is computed and then discarded because the invocation mode is static, the reference is not examined to see whether it is null:

class Test1 {
    static void mountain() {
        System.out.println("Monadnock");
    }
    static Test1 favorite(){
        System.out.print("Mount ");
        return null;
    }
    public static void main(String[] args) {
        favorite().mountain();
    }
}

which prints:

Mount Monadnock

Here favorite() returns null, yet no NullPointerException is thrown.

Tunaki
  • 132,869
  • 46
  • 340
  • 423
  • This means the compiler rewrites the call to be executed on the `Class` singleton right ? Why do they allow that ? – Dici Sep 05 '15 at 21:02
  • I'd rather give this [link](https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.8) – Finkelson Sep 05 '15 at 21:06
  • Actually I know the spec. What is the most interesting question here is why Java creators made this feature. – Finkelson Sep 05 '15 at 21:08
  • According to the spec on your link, static methods are not inherited from superinterfaces (probably to avoid multiple inheritance conflicts). I wonder what are the advantages of this inheritance for classes. Interesting – Dici Sep 05 '15 at 21:11
  • Yes, it's interesting. – Finkelson Sep 05 '15 at 21:19
3

It's called inheritance. A subclass inherits public members of the parent class, including static methods. The important thing is that the static method is not bound to any instance. You could just do:

UtilImpl.fun();
AbstractUtil.fun();

As far as the compiler is concerned, it's the same thing. The only difference is that your code creates objects but these are not relevant to the way the methods are called (plus as @Dici said in the comments you should have also gotten a warning from the compiler).

M A
  • 71,713
  • 13
  • 134
  • 174
  • He is also calling static methods from instances, you might want to add something on this – Dici Sep 05 '15 at 20:59