Per this answer and this answer, Java static methods aren't virtual and can't be overridden. Intuitively, therefore, this should work (even if in 99% of cases it's dangerous programming):
class Foo { public static String frob() { return "Foo"; } } class Bar extends Foo { public static Number frob() { return 123; } }
However, in practice this gets you:
Foo.java:10: frob() in Bar cannot override frob() in Foo; attempting to use incompatible return type found : java.lang.Number required: java.lang.String public static Number frob() { ^
Naively, it seems like Foo.frob()
and Bar.frob()
should have nothing to do with one another; yet Java insists that they do. Why?
(N.b.: I don't want to hear why it would be a bad idea to code this way, I want to hear what it is in Java and/or the JVM design that makes this restriction necessary.)
Updated to add: For those who think the compiler's going to get confused by calling static methods on instances, if you allow this: it won't. It already has to figure this out in the case where the method signatures are compatible:
class Foo { static String frob() { return "Foo"; } } class Bar extends Foo { static String frob() { return "Bar"; } } class Qux { public static void main(String[] args) { Foo f = new Foo(); Foo b = new Bar(); Bar b2 = new Bar(); System.out.println(f.frob()); System.out.println(b.frob()); System.out.println(b2.frob()); } }
gets you:
Foo Foo Bar
The question is, what's the concrete reason why it couldn't as easily (in the incompatible-signatures case) get you:
Foo Foo 123
No, we cannot override static methods because method overriding is based on dynamic binding at runtime and the static methods are bonded using static binding at compile time. So, we cannot override static methods. The calling of method depends upon the type of object that calls the static method.
No, you cannot overload a method based on different return type but same argument type and number in java.
Yes. It is possible for overridden methods to have different return type . But the limitations are that the overridden method must have a return type that is more specific type of the return type of the actual method.
Overloading is the mechanism of binding the method call with the method body dynamically based on the parameters passed to the method call. Static methods are bonded at compile time using static binding. Therefore, we cannot override static methods in Java.
Consider the following:
public class Foo { static class A { public static void doThing() { System.out.println("the thing"); } } static class B extends A { } static class C extends B { public static void doThing() { System.out.println("other thing"); } } public static void main(String[] args) { A.doThing(); B.doThing(); C.doThing(); } }
Run it! It compiles and prints out
the thing the thing other thing
Static methods sort of inherit -- in the sense that B.doThing
is translated into a call to A.doThing
-- and can sort of be overridden.
This seems like it was mostly a judgement call for the JLS. The most specific way the JLS seems to address this, though, is section 8.2, which simply doesn't say that static methods aren't inherited.
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