为什么 Java 对重写的静态方法强制返回类型兼容性?

2024-01-06

Per 这个答案 https://stackoverflow.com/questions/2223386/why-doesnt-java-allow-overriding-of-static-methods and 这个答案 https://stackoverflow.com/questions/6609842/what-does-redefining-static-methods-mean-in-java,Java 静态方法不是虚拟的,不能被重写。因此,直观上来说,这应该可行(即使在 99% 的情况下这是危险的编程):

class Foo
{
    public static String frob() {
        return "Foo";
    }
}

class Bar extends Foo
{
    public static Number frob() {
        return 123;
    }
}

然而,在实践中这会让你:

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() {
                         ^

天真地看来,Foo.frob() and Bar.frob()彼此之间不应有任何关系;但 Java 坚持认为他们这样做。为什么?

(注意:我不想听为什么以这种方式编码是一个坏主意,我想听听 Java 和/或 JVM 设计中的什么使得这种限制成为必要。)


更新添加:对于那些认为编译器会因在实例上调用静态方法而感到困惑的人,如果您允许这样做:它不会。在方法签名的情况下它已经必须弄清楚这一点are兼容的:

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());
    }
}

让你:

Foo
Foo
Bar

问题是,它不能轻易(在不兼容签名的情况下)让你得到的具体原因是什么:

Foo
Foo
123

考虑以下:

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();
  }
}

运行!它编译并打印出来

the thing
the thing
other thing

静态方法有点继承——从某种意义上说B.doThing被翻译成一个调用A.doThing——并且可以被覆盖。

这似乎主要是对 JLS 的判断。不过,JLS 似乎解决这个问题的最具体方法是第 8.2 节 http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.2,这根本没有说静态方法aren't遗传。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 Java 对重写的静态方法强制返回类型兼容性? 的相关文章

随机推荐