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(使用前将#替换为@)