首页 文章

接口方法中的最终参数 - 重点是什么?

提问于
浏览
177

在Java中,在接口方法中定义 final 参数并且在实现类中不遵守它是完全合法的,例如:

public interface Foo {
    public void foo(int bar, final int baz);
}

public class FooImpl implements Foo {

    @Override
    public void foo(final int bar, int baz) {
        ...
    }
}

在上面的示例中, barbaz 在类VS接口中具有相反的 final 定义 .

以同样的方式,当一个类方法扩展另一个类方法时,不会强制执行 final 限制,无论是否为 abstract .

虽然 final 在类方法体内有一些实用 Value ,但是有没有为接口方法参数指定 final 的点?

5 回答

  • 5

    我相信它可能是一个多余的细节,因为它是否是最终的实现细节 .

    (类似于将接口中的方法/成员声明为public . )

  • 89

    在子类中插入实现方法时,某些IDE将复制抽象/接口方法的签名 .

    我不相信它对编译器有任何影响 .

  • 17

    方法参数的最终注释始终仅与调用方永远不会与方法实现相关 . 因此,没有真正的理由在接口方法签名中使用它们 . 除非您希望在所有方法签名中遵循相同的一致编码标准,这需要最终方法参数 . 能够这样做很高兴 .

  • 23

    Update: 下面的原始答案是在没有完全理解问题的情况下编写的,因此没有直接解决问题 :) 尽管如此,对于那些希望了解 final 关键字的一般用法的人来说,它必须是提供信息的 .

    关于这个问题,我想引用我自己的评论 .

    我相信你不会被迫实施论证的最终结果,让你自由决定它是否应该是你自己实现的最终决定 . 但是,是的,您可以在界面中将其声明为final,但在实现中将其设置为非final,这听起来很奇怪 . 如果有的话,这将更有意义:a . 接口(抽象)方法参数不允许使用final关键字(但您可以在实现中使用它),或b . 在接口中将参数声明为final将强制它在实现中声明为final(但不强制用于非终结) .


    我可以想到方法签名可以有 final 参数的两个原因: BeansObjects (实际上,它们是相同的原因,但是上下文略有不同 . )

    Objects:

    public static void main(String[] args) {
        StringBuilder cookingPot = new StringBuilder("Water ");
        addVegetables(cookingPot);
        addChicken(cookingPot);
        System.out.println(cookingPot.toString());
        // ^--- OUTPUT IS: Water Carrot Broccoli Chicken ChickenBroth 
        //      We forgot to add cauliflower. It went into the wrong pot.
    }
    
    private static void addVegetables(StringBuilder cookingPot) {
        cookingPot.append("Carrot ");
        cookingPot.append("Broccoli ");
        cookingPot = new StringBuilder(cookingPot.toString());
        //   ^--- Assignment allowed...
        cookingPot.append("Cauliflower ");
    }
    
    private static void addChicken(final StringBuilder cookingPot) {
        cookingPot.append("Chicken ");
        //cookingPot = new StringBuilder(cookingPot.toString());
        //     ^---- COMPILATION ERROR! It is final.
        cookingPot.append("ChickenBroth ");
    }
    

    final 关键字确保我们在尝试这样做时通过显示编译错误不会意外地创建新的本地烹饪锅 . 这确保了将鸡汤添加到我们原来的烹饪锅中,这种方法得到了 addChicken 方法 . 将此与 addVegetables 相比较,我们丢失了花椰菜,因为它将其添加到新的当地烹饪锅而不是原来的锅中 .

    Beans: 它与对象的概念相同(如上所示) . Java本质上是 Object s . 但是,bean(JavaBeans)在各种应用程序中用作存储和传递已定义的相关数据集合的便捷方式 . 就像 addVegetables 可以通过创建一个新的烹饪锅 StringBuilder 并用花椰菜扔掉它来搞乱烹饪过程一样,它也可以用烹饪锅JavaBean做同样的事情 .

  • 2

    看起来不像 . 根据Java Language Specification 4.12.4

    声明变量final可以作为有用的文档,它的值不会改变,可以帮助避免编程错误 .

    但是,在重写方法的rules for matching signatures中未提及方法参数上的 final 修饰符,并且它仅对调用方没有影响,仅在实现的主体内 . 另外,正如Robin在评论中所指出的,方法参数上的 final 修饰符对生成的字节代码没有影响 . (对于 final 的其他用途,情况并非如此 . )

相关问题