请考虑以下代码:
class A{
public static void m(Number n){
System.out.println("Number A");
};
}
class B extends A{
public static int m(Number n){
System.out.println("Number B");
return 1;
};
}
输出:
java: m(java.lang.Number) in inheritanceTest.B cannot override m(java.lang.Number) in inheritanceTest.A return type int is not compatible with void
我知道静态方法不涉及多态性,因此我推断我的代码不可能覆盖。这个编译器消息对我来说很奇怪。
据我所知,覆盖是多态性的一部分。我准备scjp,我怕在熟悉的问题上出错。
请澄清这个问题。
我的预期行为 - 关于重载错误的消息
P.S1.
我已经阅读了关于静态覆盖的 HitTest 门问题,但我没有找到答案(
P.S2. 根据 Pshemo 的回答:
这段代码:
class Foo{
public static void m(Number n){
System.out.println("Number A");
};
public static int m(Number n){
System.out.println("Number B");
return 1;
};
}
输出:
error: method m(Number) is already defined in class Foo
public static int m(Number n){
^
1 error
对我来说,这些情况是一样的。但是编译器错误是不同的 - 很奇怪。
最佳答案
JLS §8.4.8.3(Java 8)说:
If a method declaration d1 with return type R1 overrides or hides the declaration of another method d2 with return type R2, then d1 must be return-type-substitutable (§8.4.5) for d2, or a compile-time error occurs.
同样的规则适用于实例方法和静态方法,因为它表示“覆盖或隐藏”。基本上,如果您有一个具有相同名称和相同参数的方法,如果它是实例方法,它会覆盖,但如果它是类(静态)方法,则会隐藏(继承的方法)。在这两种情况下,返回类型必须相同或遵守协变规则。
因为它是同一条规则,很可能编译器代码中只有一个地方检查这条规则,如果违反了这条规则,你就会得到你所看到的错误,我敢肯定这是更多常见现象。编译器真的应该检查它是否应该说“覆盖”或“隐藏”,但看起来他们滑倒了。完全正确地获取错误消息通常不是编译器编写者的最高优先级——与确保应该编译的代码正确运行并且不应该编译的代码不正确运行相比,这不是最重要的。所以我认为这是一个缺陷,但是是一个非常小的缺陷。
关于java - 为什么如果静态方法不涉及多态性(后期绑定(bind))我会看到无法覆盖静态方法的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23573726/