界面方法中的最后一个参数 – 有什么意义?
在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) { ... } }
在上面的例子中, bar
和baz
在类VS接口中有相反的final
定义。
以同样的方式,当一个类方法扩展另一个时,没有final
限制,无论是abstract
还是非abstract
。
当final
方法体内部有一些实用的值时,有没有指定final
方法的参数?
这看起来不像。 根据Java语言规范4.12.4 :
声明variablesfinal可以作为有用的文档,它的值不会改变,并且可以帮助避免编程错误。
但是,在匹配重写方法的签名的规则中没有提到方法参数的final
修饰符,它只对调用者有效,只在实现的主体内。 此外,正如Robin在注释中指出的,方法参数的final
修饰符对生成的字节码没有影响。 (对于final
其他用途,这是不正确的。)
在子类中插入实现方法时,一些IDE将复制abstract / interface方法的签名。
我不相信这对编译器有什么影响。
方法参数的最终注释始终只与调用方的方法实现无关。 因此,在接口方法签名中没有真正的理由使用它们。 除非您想要遵循所有方法签名中需要最终方法参数的相同的一致编码标准。 那么能够这样做是很好的。
更新:下面的原始答案是在没有完全理解问题的情况下编写的,因此并不直接解决问题:)
尽pipe如此,对于那些希望了解final
关键字的一般用法的人来说,它必须是有用的。
至于这个问题,我想从下面引用我自己的意见。
我相信你不是被迫执行最终的争论,让你自由决定是否应该是最终的或不是在你自己的执行。
但是,是的,听起来很奇怪,你可以在界面中声明它,但是在实现中它是非最终的。 如果出现以下情况,情况会更加明显:
一个。
final
关键字不允许用于接口(抽象)方法参数(但可以在实现中使用它),或者
湾 在接口中声明一个final
的参数会迫使它在实现中被宣布为final
(但不是被强制进入非决赛)。
我可以想出为什么方法签名可以有final
参数的两个原因: Bean和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
关键字确保我们不会在我们尝试这样做时出现编译错误,从而无意中创build了新的本地烹饪锅。 这确保鸡肉汤被添加到我们原来的addChicken
方法得到的烹饪锅。 比较addVegetables
,我们失去了花椰菜addVegetables
,因为它添加到一个新的当地的烹饪锅,而不是原来的锅。
豆类:与物体的概念相同(如上所示) 。 豆本质上是Java中的Object
。 然而,bean(JavaBean)在各种应用程序中用作存储和传递定义的相关数据集合的便捷方式。 就像addVegetables
可以通过创build一个新的烹饪锅StringBuilder
并把它扔到花椰菜里一样,它可能会搞乱烹饪过程,也可以用一个烹饪锅JavaBean来做。
我相信这可能是一个多余的细节,因为它是否是最终的是一个实现细节。
(有点像在公共接口中声明方法/成员一样)