Mr_*_*s_D 6 java inheritance final
所以我需要在下面的案例中重复最终决定吗?
interface Foo {
void meth(final Bar bar);
}
public Baz implements Foo {
@Override
void meth(/* is it final ?*/ Bar bar){}
}
Run Code Online (Sandbox Code Playgroud)
问题不仅是接口继承,还有类继承 - 我猜答案是一样的
是的,您需要重新声明方法参数,final
就像您希望编译器确保在当前方法中永远不会重新分配这些参数一样.当覆盖接口和类定义时,这同时适用.
原因很简单:这是Java语言规范中指定的行为.但是,编译器甚至无法检查是否重新分配final
参数,即使它想要:
final
方法范围中变量的修饰符实际上并未转换为字节代码或在别处写入Java类文件格式.它在编译特定类或接口后基本消失,并且在编译后无法跟踪.由于每个类和接口都是独立于其他类和接口编译的,因此编译器或JVM运行时验证程序无法确保final
在子类或接口实现中为参数分配了新值.它只在单个类的编译中,Java编译器可以确保不会发生此类分配.final
因此,参数声明对于类是本地的,并且不可能在将来更改此行为或通过使用运行时反射来查找此功能.
final
因此,在抽象方法签名中使用参数不会有用,无论是真实的还是纪录的:由于Java 通过值调用而不是通过引用来实现方法调用,因此final
修饰符永远不会影响实现方法范围之外的代码.因此,如果重新分配方法参数变量,则仅仅是方法实际实现的细节.因此,我个人从不使用它来定义类或接口中的抽象方法.这是允许的,但没有意义.
在非抽象方法定义中,声明方法变量final
仅用于以下两个目的之一:
final
修饰符也可以作为某种文档.更新:从Java 8开始,如果方法参数是合成的(在源代码中未表示,强制要求(隐含地存在于源代码中,例如this
lambda表达式的引用)或者是否合成,则归因于方法参数final
.但这不会影响重写方法final
需要重复声明才能设置此标志.此外,Java语言没有注意这些标志,只有元框架才能读取这些标志来实现可能对这些标志作出反应的逻辑.