问题

我一直在玩静态方法的修饰符,并遇到了一个奇怪的行为。

我们知道,静态方法不能被覆盖,因为它们与类而不是实例相关联。

所以,如果我有下面的片段,它编译得很好

//Snippet 1 - Compiles fine
public class A {
    static void ts() {
    }
}

class B extends A {
    static void ts() {
    }
}

但是如果我在A类中将final修饰符包含到静态方法中,那么编译失败在B中的ts()不能覆盖A中的ts();重写方法是静态最终

当静态方法根本无法覆盖时,为什么会发生这种情况?


#1 热门回答(138 赞)

静态方法不能被覆盖,但可以隐藏它们。 B的ts()方法没有覆盖(不受多态性)ats()的A但它会隐藏它。如果你打电话ts()in B(NOTA.ts()B.ts() ...... justts()),将调用B中的一个而不是A.因为这不受多态性的影响,所以A中的callts()永远不会被重定向到B中的那个。

keywordfinal将禁止隐藏该方法。因此它们无法隐藏,尝试这样做会导致编译器错误。

希望这可以帮助。


#2 热门回答(11 赞)

静态方法无法覆盖

这不完全正确。示例代码实际上意味着B中的方法ts隐藏了A中的方法ts。因此它不完全覆盖。在onJavaranch上有一个很好的解释。


#3 热门回答(9 赞)

静态方法属于类,而不是实例。

A.ts()B.ts()总是会成为单独的方法。

真正的问题是Java允许你在实例对象上调用静态方法。当从子类的实例调用时,具有来自父类的相同签名的静态方法是hidden。但是,你无法覆盖/隐藏final methods

你会认为错误消息将使用隐藏字而不是覆盖...


原文链接