You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin抽象父类依赖未初始化抽象var致崩溃,如何正确实现?

Kotlin抽象var未初始化崩溃的解决方案

问题原因

原代码执行时会崩溃,核心是类初始化顺序冲突:创建B实例时,会优先执行父类A的初始化逻辑。A中直接初始化val c = C(string),但此时子类B的string还未完成赋值(子类属性初始化在父类之后),而string是抽象var,此时没有实际的初始化值,因此触发未初始化异常。

正确实现方案

以下是几种可行的解决方式,可根据实际场景选择:

方案一:延迟初始化c(改动最小,推荐)

使用lazy委托延迟c的初始化,让它在第一次被访问时才创建实例,此时子类的string已经完成赋值:

class C(val string: String) {
    init {
        println(string)
    }
}
abstract class A {
    abstract var string: String
    // 用lazy延迟初始化,第一次访问c时才会执行C(string)
    val c by lazy { C(string) }
}
class B : A() {
    override var string = "string"
}

fun main() {
    val b = B()
    b.c // 此时才会初始化c,string已有值
}

方案二:将c改为抽象属性,由子类实现

把c定义为抽象属性,让子类在完成string初始化后再创建C实例,确保依赖的string已就绪:

class C(val string: String) {
    init {
        println(string)
    }
}
abstract class A {
    abstract var string: String
    abstract val c: C
}
class B : A() {
    // 先初始化string,再初始化c
    override var string = "string"
    override val c = C(string)
}

fun main() {
    B() // 初始化顺序安全,不会崩溃
}

方案三:通过父类构造函数传递参数

调整类结构,让父类A通过构造函数接收string参数,这样父类初始化时就能拿到明确的值,避免依赖子类的未初始化属性:

class C(val string: String) {
    init {
        println(string)
    }
}
abstract class A(string: String) {
    var string: String = string
    val c = C(string)
}
class B : A("string") {
    // 若需要可在此重写string,也可直接使用父类的属性
}

fun main() {
    B()
}

内容的提问来源于stack exchange,提问作者Ofek Ron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 09:25:34