Kotlin中属性初始化器与属性getter的选择最佳实践及适用时机
Kotlin两种只读属性定义方式的选择指南
嘿,这个问题算是Kotlin属性初始化里的高频困惑了,咱们直接拆解这两种写法的核心差异,再聊聊各自的适用时机:
第一种:立即初始化的只读属性 (val y = Z)
这种写法的本质是在类/对象初始化阶段执行一次Z的计算,然后把结果缓存起来,后续每次访问y都是直接取缓存好的值,不会再重新计算Z。
适用场景:
- 当
Z的计算结果是固定不变的,或者只需要在初始化时确定一次的时候:比如依赖注入的实例、固定的配置常量、从构造参数衍生的静态值。 - 当
Z是耗时/重计算操作时:比如创建一个大对象、执行一次复杂的数据库查询,用这种方式可以避免重复计算带来的性能损耗。 - 简单场景下的快速声明:比如不需要动态逻辑的只读属性,这种写法更简洁。
举个实际例子:
class Book(val publishYear: Int) { // 初始化时计算一次,之后isRecent的值固定 val isRecent = publishYear >= 2020 }
第二种:动态计算的只读属性 (val y: Y get() = Z)
这种写法的核心是每次访问y的时候,都会重新执行get()块里的Z计算,返回最新的结果。虽然y是只读属性(不能直接赋值),但它的值会随着依赖的变量动态变化。
适用场景:
- 当
y的值需要实时反映最新状态时:比如依赖其他可变属性的衍生值、获取当前时间、读取某个实时更新的系统状态。 - 重写父类属性时需要自定义访问逻辑:比如父类有一个只读属性,子类需要每次访问都返回不同的结果,这种写法是标准的重写方式。
- 当
Z的计算非常轻量,或者必须保证每次都是最新值时:比如简单的算术运算、读取一个经常变化的变量。
举个对比例子:
class DynamicBook(val publishYear: Int) { // 每次访问都会重新计算,若publishYear是var类型,结果会实时更新 val isRecent: Boolean get() = publishYear >= 2020 } // 实时获取当前时间的场景 object Clock { val currentTime: Long get() = System.currentTimeMillis() }
关键权衡点
- 性能:第一种写法只计算一次,性能更优;第二种每次访问都计算,若
Z是重操作会有性能开销。 - 时效性:第一种值固定,第二种值实时更新。
- 代码简洁性:简单固定值用第一种,动态逻辑用第二种。
内容的提问来源于stack exchange,提问作者Nikola Mihajlović
相关产品推荐
相关产品推荐

