651.288.7000 info@intertech.com

Recently, I had a quick chat with a colleague on static methods in parent and sub-classes with the same signature. The source of the conversation was the terms “hiding” vs. “overriding”, and why “hiding static methods” is correct and works but “overriding static methods” is incorrect and does not work.

TL;DR “You can’t override static methods”, because the JVM executes static methods on the declared reference class, not the defined runtime/instance class.

A simple example shows a few different static method execution contexts, illustrating the results:

package com.intertech.hidestaticmethod;

public class Parent {
    public static void doSomething() {
        System.out.println("PARENT");
    }
}
package com.intertech.hidestaticmethod;

public class Child extends Parent {
    public static void doSomething() {
        System.out.println("CHILD");
    }

    public static void main(final String[] args) {
        final Parent parentAsParent = new Parent();
        // calls parent's
        parentAsParent.doSomething();

        final Parent childAsParent = new Child();
        // calls parent's
        childAsParent.doSomething();

        final Child childAsChild = new Child();
        // calls child's
        childAsChild.doSomething();

        // same class static context (most local)
        doSomething();
    }
}

The main method comments state the execution results.  The results show that the called static method is the one for the defined reference.

Running the child class as a Java app (the main method) outputs:

PARENT
PARENT
CHILD
CHILD

It’s no different than replacing the instance method calls with the more correct static reference call:

package com.intertech.hidestaticmethod;

public class Child extends Parent {
    public static void doSomething() {
        System.out.println("CHILD");
    }

    public static void main(final String[] args) {
        // calls parent's
        Parent.doSomething();

        // calls parent's
        Parent.doSomething();

        // calls child's
        Child.doSomething();

        // same class static context (most local)
        Child.doSomething();
    }
}

Hopefully this post helps explain hiding static methods – why we cannot override static methods but we can hide static methods.