I was reading about shadowing static methods, and I can't understand one thing, how compiler chose method to run. Suppose I have 3 classes.
public static class A {
public static int test() {
return 1;
}
}
public static class B extends A {
public static int test() {
return 2;
}
}
public static class C extends B {
public static int test() {
return 3;
}
}
Obviously when I call method A.test()
B.test()
C.test()
i will have results 1
2
3
But if i call it from instance (I know bad practice), then When this code:
C c = new C();
System.out.println(c.test());
will print out 3 as i expect, but when I do
B b = c;
System.out.println(b.test());
then my output will be 2.
Which is surprising for me, as b
was instantiate as object of class C
. Any reason why it was implemented like that?
Shadowing (method hiding) A method or function of the base class is available to the child (derived) class without the use of the "overriding" keyword. The compiler hides the function or method of the base class. This concept is known as shadowing or method hiding.
Method hiding can be defined as, "if a subclass defines a static method with the same signature as a static method in the super class, in such a case, the method in the subclass hides the one in the superclass." The mechanism is known as method hiding. It happens because static methods are resolved at compile time.
then my output will be 2. Which is surprising for me, as b was instantiate as object of class C. Any reason why it was implemented like that?
Static method's bind to Type rather than instance. So the right side part doesn't matter in case of static method.
Inshort, static members belongs to class rather than instance.
Refer the JLS : 15.12.4. Run-Time Evaluation of Method Invocation
The decision is made by the compiler, always, and is based on the declared type of the variable. The runtime type of the object -- which is what matters for instance methods -- isn't considered at all. In fact, you can call static methods through a reference variable which is set to null, and it will work just fine.
First and foremost accessing static methods through instances is bad & compiler should have given you a warning. You should heed it. Then when you invoke b.test
the type of b
is B not C as you are expecting. So B.test
is invoked.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With