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

min*_*das 185 java methods final interface class

在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) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,bar并且在类VS的接口中baz有相反的final定义.

以同样的方式,final当一个类方法扩展另一个类时,不会强制执行任何限制abstract.

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

Ted*_*opp 98

看起来不像.根据Java语言规范4.12.4:

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

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

  • 它不能用于匹配签名,因为它不会出现在实际的.class文件中.它仅适用于编译器. (11认同)
  • 然而,文档几乎是无用的,因为在实现类上没有强制使用 `final` 修饰符。您的界面签名可能只是撒谎。 (3认同)

Pet*_*rey 24

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

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

编辑:虽然我认为这在过去是正确的,但我认为现在的IDE不再这样做了.

  • 有效点,虽然我不认为实现此功能时(或意外离开)有很多IDE :-) (2认同)
  • 我认为属于"静态瞬态"字段.;) (2认同)

jmg*_*jmg 17

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


ADT*_*DTC 6

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

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

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

但是,是的,您可以final在界面中声明它,但在实现中将其作为非最终版本,这听起来很奇怪.如果有以下情况,那将更有意义:

一个. final接口(抽象)方法参数不允许使用关键字(但您可以在实现中使用它),或
b.final在接口中声明参数将强制它final在实现中声明(但不强制用于非终结).


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

对象:

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 ");
}
Run Code Online (Sandbox Code Playgroud)

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

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