Java是否会阻止覆盖静态方法?

Is Java prevent overriding static methods?

本问题已经有最佳答案,请猛点这里访问。

我不明白为什么当我尝试编译此代码时编译器显示错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A
{
    public static void f()
    {
        System.out.println("A.f()");
    }
}

class B extends A
{
    public static int f()
    {
        System.out.println("B.f()");
        return 0;
    }
}

A类和B类中两个方法之间的差异是返回类型,我读到Java防止重写静态方法。所以我期望编译器不会显示任何错误,因为最初没有任何重写!!


Java语言规范具有以下规则:

8.4.8.3. Requirements in Overriding and Hiding

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.

This rule allows for covariant return types - refining the return type of a method when overriding it.

因此,即使方法隐藏了超类中的一个,并且不重写它,返回类型也必须是兼容的。


B中的方法不是重写类A中的方法,您已经知道了。问题是,对于具有相同签名的类B有两个不同的方法可见。记住,返回类型不算作方法签名的一部分。

来自JLS§;8.4.2-方法签名:

Two methods have the same signature if they have the same name and argument types.

因此,类B中的方法既不是有效的重写,也不是有效的重载。因为重载要求您具有不同的方法签名,而您没有。

另外,它不是有效的方法隐藏,因为这要求隐藏方法的返回类型与父类方法的返回类型相同或子类型相同。这里也没有发生这种情况。

因此,要么将类B方法的返回类型更改为void方法,然后更改它的签名。