Kotlin 属性初始化陷阱

复制代码
open class Base {
    open val value: String = "Base class"
    init {
        println("Base class initialized: $value")
    }
}

class Derived: Base() {
    override val value: String = "Derived class"
    init {
        println("Derived class initialized: $value")
    }
}

fun main() {
    val derived = Derived()
}

运行选定的代码时,输出如下:

Base class initialized: null

Derived class initialized: Derived class

我们的疑问就是这个 null,为啥

首选我们要确定一件事情,子类初始化,先会初始化父类。

在 Base 类的 init 块中,value 属性被访问。
由于 Derived 类覆盖了 value 属性,并且 Derived 的 value 尚未初始化(因为 Base 的初始化先于 Derived),此时 value 的值为 null。

Derived 类的初始化顺序:

Derived 的 value 属性被初始化为 "Derived class"。

然后执行 Derived 的 init 块,打印 "Derived class initialized: Derived class"。

其实这里有个警告的 Accessing non-final property value in constructor ,建议我们去掉 open,使value 变成 final 属性不可被子类重写,从而避免警告。这样也不会输出 null。

所以大家要重视警告,避免不必要的异常。

避免在构造函数或init块中调用可被重写的方法

使用final保护关键方法

相关推荐
低调小一1 小时前
Swift 语法学习指南 - 与 Kotlin 对比
微信·kotlin·swift
叽哥7 小时前
Kotlin学习第 3 课:Kotlin 流程控制:掌握逻辑分支与循环的艺术
android·java·kotlin
用户097 小时前
Gradle 现代化任务依赖方案
android·kotlin
前行的小黑炭19 小时前
Android 协程的使用:结合一个环境噪音检查功能的例子来玩玩
android·java·kotlin
Android-Flutter1 天前
kotlin - 平板分屏,左右拖动,2个Activity计算宽度,使用ActivityOptions、Rect(三)
android·kotlin
前行的小黑炭2 天前
Android :为APK注入“脂肪”,论Android垃圾代码在安全加固中的作用
android·kotlin
tangweiguo030519872 天前
Android Kotlin 动态注册 Broadcast 的完整封装方案
android·kotlin
前行的小黑炭2 天前
Android 不同构建模式下使用不同类的例子:如何在debug模式和release模式,让其使用不同的类呢?
android·kotlin·gradle
Android-Flutter2 天前
kotlin - 2个Fragment实现左右显示,左边列表,右边详情,平板横、竖屏切换
android·kotlin
木头左3 天前
结合机器学习的Backtrader跨市场交易策略研究
人工智能·机器学习·kotlin