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

时间:2011-03-21 15:53:47

标签: java class interface methods final

在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在类方法体内有一些实用价值,但是有没有为接口方法参数指定final的点?

5 个答案:

答案 0 :(得分:93)

似乎没有任何意义。根据{{​​3}}:

  

声明变量final可以发挥作用   作为有用的文件,它的价值   不会改变,可以帮助避免   编程错误。

但是,在覆盖方法的Java Language Specification 4.12.4中未提及方法参数上的final修饰符,并且它对调用方没有影响,仅在实现的主体内。此外,正如Robin在评论中所指出的,方法参数上的final修饰符对生成的字节代码没有影响。 (对于final的其他用途,情况并非如此。)

答案 1 :(得分:23)

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

我认为它对编译器没有任何影响。

编辑:虽然我认为过去这是真的,但我认为目前的IDE不再这样做了。

答案 2 :(得分:17)

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

答案 3 :(得分:6)

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

关于这个问题,我想从下面引用我自己的评论。

  

我相信你不会被迫实施论证的最终结果,让你自由决定它是否应该最终或者你自己的实现。

     

但是,是的,您可以在界面中声明它final,但在实现中将它非最终,这听起来很奇怪。如果有的话会更有意义:

     接口(抽象)方法参数不允许使用

a。 final关键字(但您可以在实现中使用它),或者
   b。在接口中将参数声明为final将强制它在实现中声明为final(但不强制用于非决赛)。


我可以想到方法签名可以有final个参数的两个原因:对象实际上,它们都是相同的原因,但背景略有不同。

<强>物件:

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进行比较,因为它将其添加到新的本地烹饪锅而不是原来的锅中。

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

答案 4 :(得分:2)

我认为这可能是一个多余的细节,因为它是否是最终的实现细节。

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