为什么私人方法也不能是最终的?

时间:2014-04-18 19:59:00

标签: java oop methods final

privatefinal添加到同一方法是否多余?

class SomeClass {

    //--snip--

    private final void doStuff()
    {
        // private work here
    }
}

如果是private,那么任何人都无法覆盖它,对吗?

为什么可以添加final关键字,如果它没有效果? (或者我错过了什么?)

3 个答案:

答案 0 :(得分:51)

基本上,这是允许的,因为他们认为不值得设置禁止private修饰符的特殊情况。这就像你如何将接口上的方法声明为public,或者将接口中的嵌套类声明为static,即使这些关键字隐含在接口中。您还可以在final类等上声明final方法。

当你添加冗余修饰符时,Java采取了不抱怨的立场。他们一贯地做到了。

答案 1 :(得分:5)

需要私有方法为final的一个边缘情况是使用SafeVarargs注释时。以下代码无法编译,因为私有方法不是最终的。

@SafeVarargs
private void method(List<String>... stringLists) {
    //TODO a safe varargs operation
}

答案 2 :(得分:4)

它使语言更灵活,但语言不保证它会产生任何影响。使私有方法最终是对(JIT)编译器的提示。

Java语言规范notes

  

可以将方法声明为final,以防止子类覆盖或隐藏它。

     

尝试覆盖或隐藏最终方法是编译时错误。

     

私有方法和在最终类(§8.1.1.2)中立即声明的所有方法都表现得像是最终的,因为无法覆盖它们。

     

在运行时,机器代码生成器或优化器可以&#34;内联&#34;最终方法的主体,用其主体中的代码替换方法的调用。内联过程必须保留方法调用的语义。特别是,如果实例方法调用的目标为null,则即使方法是内联的,也必须抛出NullPointerException。 Java编译器必须确保在正确的位置抛出异常,以便在方法调用之前以正确的顺序评估该方法的实际参数。

From Wikipedia

  

一个常见的误解是将一个类或方法声明为final   通过允许编译器直接插入来提高效率   方法调用的任何地方(参见内联扩展)。但是因为   方法在运行时加载,编译器无法执行此操作。只有   运行时环境和JIT编译器确切地知道哪些类具有   已经加载,因此只有他们能够做出何时决定   内联,无论方法是否是最终的

     

生成直接可执行的,特定于平台的机器代码的机器代码编译器是一个例外。使用静态时   链接时,编译器可以安全地假设方法和变量   编译时可计算的内容可以内联。