在我使用的遗留代码中,我发现了以下内容:
@Autowired
final lateinit var controller: CustomController
这个final
关键字在这里是什么意思?
在Kotlin文档中,我发现了一个关于final
关键字的简短描述,该关键字阻止了对开放类中方法的重写,但没有关于字段的信息。此外,我发现该行所在的类未打开
final
属性或方法可防止重写字段/方法。也就是说,除非由关键字open
指定,否则Kotlin默认情况下认为属性或方法/函数是最终的。在您的情况下,最后一个关键字是多余的。
下面是一个小的演示测试用例来说明这一点。
open class Parent {
open val someValue = 0
final val otherValue = 13 // redundant modifier 'final' warning in Android Studio
}
class Child : Parent() {
override val someValue = 5
// override val otherValue = 19 // compile error
}
OOP中有一个有趣的问题叫做脆弱基类,以及为什么像Kotlin这样的一些语言默认情况下更喜欢final。
这里有一个属性,而不是字段。
它看起来就像一个字段,就像在Java中一样;但在Kotlin中,它实际上定义了一个公共getter方法、一个公共setter方法和一个私有backing字段*。
因此final
修饰符应用于访问器方法,防止那些在子类中被重写。(正如你所说,后备字段本身无论如何都不能被覆盖。(
正如Siddharth所说,final
是Kotlin中的默认值,因此您通常不需要指定它,尽管在某些情况下需要它——例如,如果它已经覆盖了某些内容,或者您正在使用全开放或Kotlin-spring编译器插件。(@Autowired
的使用表明这是一个Spring模块,这可能解释了为什么这里需要final
。(无论如何,IDE可能会指示不需要它的地方,例如显示为灰色。
(*只有getter是必需的;不会为val
生成setter,如果覆盖访问器而它们没有引用它,则不会生成backing字段。(