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
相关产品推荐
相关产品推荐

