接口方法的最终参数-什么'

在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定义。

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

虽然final在类方法体中有一些实用价值,但为接口方法参数指定final是否有任何意义?

35770 次浏览

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

我不相信这对编译器有任何影响。

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

方法参数的最后注释总是只与方法实现相关,而与调用者无关。因此,没有真正的理由在接口方法签名中使用它们。除非您希望在所有方法签名中遵循相同的一致编码标准,该标准要求最终的方法参数。那么能够这样做就很好了。

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

(有点像将接口中的方法/成员声明为public。)

这似乎没有任何意义。根据Java语言规范4.12.4:

声明一个变量final可以使用 作为有用的文档说明其价值 会不会改变又能不能帮助避免 编程错误。< / p >

然而,方法参数上的final修饰符不会在被覆盖方法的签名匹配规则中提到,而且它只在实现体中对调用者起作用。另外,正如Robin在注释中指出的那样,方法参数上的final修饰符对生成的字节码没有影响。(这对于final的其他用法不是这样的。)

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

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

我相信你不会被迫实现一个参数的终结性,让你在自己的实现中自由决定它是否应该是最后

但是,这听起来相当奇怪,你可以在接口中声明它final,但在实现中有最后。如果有以下任何一种情况会更有意义:

一个。 final关键字不允许作为接口(抽象)方法参数(但你可以在实现中使用它),或
b.在接口中将实参声明为final将强制在实现中将其声明为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进行比较,在addVegetables中,我们丢失了花椰菜,因为它将花椰菜添加到新的当地的烹饪锅中,而不是原来的锅中。

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