final 方法在 java 中的确切工作方式

exact way how final methods works in java

class Clidder {
    private final void flipper() {
        System.out.println("Clidder");
    }
}
public class Clidlet extends Clidder {
    public final void flipper() {
        System.out.println("Clidlet");
    }
    public static void main(String args[]) {
        new Clidlet().flipper();
    }
}

结果如何?对于这个问题,我期待答案 "compilation fails" 因为 final 方法不能被覆盖并且它不允许继承。但答案是 "Cliddet" 这是为什么?我是否误解了这个概念中的某些内容。这怎么可能是输出?请解释。

private修饰符表示Clidder的class中的flipper()方法在子classClidlet中是看不到的。所以它不是覆盖,而是看起来像子 class 中的新方法声明。 Private method/field 无法覆盖,因为它不可见。

private方法没有被覆盖,所以这里没有覆盖,所以没有违反final。事实上 finalprivate 方法上是没有意义的,或者是多余的,你自己挑吧。

答案应该是 "Cliddet",因为您的最终方法具有 private 访问修饰符,这使得它对子 class 不可见。 Clidlet class 中的 flipper 方法有效地隐藏了父 class 中的相同方法。这是非常危险的,因为结果将取决于它是从 superclass 还是 subclass 调用的。

Clidlet  clidlet = new Clidlet();
clidlet.flipper(); // prints Clidlet

Clidder clidder = new Clidlet(); 
clidder.flipper(); // prints Clidder

在这种情况下,private 关键字阻止子类访问该方法。结果 Clidlet 询问 Clidder 关于方法属性,收到响应 "I keep it private" 并执行它自己的方法。

这个案例说明 private 先于(优先级高于)finalprivate final== private 并展示了它可能导致的混淆到.