Kotlin 提供对属性重写的支持。我想知道将属性覆盖为常量值的最佳方法是什么。
更具体地说,假设抽象
val
属性在超类或接口中声明:
// In a superclass or an interface
abstract val num : Int
在它的子类中,据我所知至少有两种方法可以覆盖它:
// In its subclass
override val num : Int = 0
或
// In its subclass
override val num : Int get() = 0
除了这两种,我还可以用Java的方式来做:
// In a superclass or an interface
abstract fun getNum() : Int
// In its subclass
override fun getNum() : Int = 0
三者在内存和生成的字节码方面有什么区别?哪一个是最好的?
Kotlin 中是否有更好的方法或模式来声明要重写为常量的属性?
存在功能差异。
使用赋值在创建对象时初始化字段:
override val num : Int = 0
这将创建一个隐式的最终支持字段,其值为
0
,并且 getter 始终返回相同的值。这是反编译成java生成的字节码:
private final int num;
public int getNum() {
return this.num;
}
第二个声明实际上是一个 getter override,这也是从接口实现属性的有效方法。这不会创建支持字段,因此您的属性可以在每次调用时返回不同的值(例如方法调用):
override val num : Int get() = 0
反编译字节码:
public int getNum() {
return 0;
}
最初的方法涉及在每个对象字段中存储常量引用。尽管与第二个选项相比,此方法不会显着影响内存或性能,但它提供了增强的可读性。因此,我建议选择第一种方法,阅读更多...