为什么 Java 对重写的静态方法强制实施返回类型兼容性?
2022-09-01 12:15:55
根据这个答案和这个答案,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() {
^
天真地,它似乎并且不应该彼此无关;然而Java坚持认为他们是这样做的。为什么?Foo.frob()
Bar.frob()
(注意:我不想听到为什么以这种方式编码是一个坏主意,我想听听Java和/或JVM设计中是什么使得这种限制成为必要。
更新以添加:对于那些认为编译器会因为在实例上调用静态方法而感到困惑的人,如果你允许这样做:它不会。在方法签名兼容的情况下,它已经必须弄清楚这一点:
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