Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Java enforce return type compatibility for overridden static methods?

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 
like image 331
David Moles Avatar asked Feb 24 '12 23:02

David Moles


People also ask

What happens if we override static method in Java?

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.

Does return type matter in method overriding in Java?

No, you cannot overload a method based on different return type but same argument type and number in java.

Should return type be same in overriding?

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.

Why we Cannot override static methods in Java?

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.


1 Answers

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.

like image 168
Louis Wasserman Avatar answered Sep 22 '22 00:09

Louis Wasserman