Have you ever found yourself in a situation where you have to optimize a piece of code(code with lots of objects) ? Well, don’t worry if you haven’t encountered yet, eventually you will. This post will be about a confusing scenario of Static methods and method overriding.

Static is a keyword in Java which is helpful in memory management. It can be used with classes, variables, methods and blocks.

Static members belong to the class instead of a specific instance, this means if you make a member static, you have the option to optimize and access it without object(You can also access it with objects). Only one instance of a static field exists even if you create a million instances of the class. It will be shared by all instances in memory. On the other hand, for non-static methods, we must need to create an object of the class in order to call it. Below example will help you understand the concept better:

class TestA {
    public static int sum(int a, int b) {
        return a+b;
    }

    public int foo(int a, int b) {
        return a+b;
    }
}

class TestB extends TestA {
    public static int sum(int a, int b) {
        return a-b;
    }
    public int foo(int a, int b) {
        return a-b;
    }
}

public class TestRunner {
    public static void main(String[] args) {
        //Section 1
        System.out.println(“Calling the static methods without object creation”);
        System.out.println(TestA.sum(1,2));
        System.out.println(TestB.sum(1,2));
        TestB test1 = new TestB();
        TestA test2 = new TestB(); // Notice the reference variable and actual reference are of different classes
        TestA test3 = new TestA();
        //Section 2
        System.out.println(“Calling the non-static methods with object creation and method overriding”);
        System.out.println(test1.foo(1,2));
        System.out.println(test2.foo(1,2)); // line 1
        System.out.println(test3.foo(1,2));
        //Section 3
        System.out.println(“Calling the static methods with object creation and method overriding”);
        System.out.println(test1.sum(1,2));
        System.out.println(test2.sum(1,2)); // line 2
        System.out.println(test3.sum(1,2));
    }
}

Output:

Calling the static methods without object creation
3
-1
Calling the non-static methods with object creation and method overriding
-1
-1
3
Calling the static methods with object creation and method overriding
-1
3
3

Lets see what’s happening here.

test1 and test3 are objects of classes TestB and TestA respectively whereas test2 is variable of class TestA but it holds the reference of class TestB.

Section 1 : This section of code shows you how to call static methods with objects. They are directly called using the class name.

Section 2 : This section of code shows you how to call non-static methods and their behavior in the case of method overriding. If we call non static method foo() from test2 object(see comment //line 1), it will be handled by actual reference i.e. TestB. This is the reason why the output here is -1

Section 3 : This section of code shows you how to call static methods without creating objects and their behavior in the case of method overriding. If we call static method sum() from test2 object(see comment //line 2), it will be handled by the class of reference variable i.e. TestA. This is the reason why the output here is 3

source: https://codeburst.io/static-methods-and-method-overriding-d810f30f3c18