Kotlin data class次构造函数实例属性丢失问题求解
问题根源
你的次级构造函数实现逻辑有本质缺陷:
- 两个次级构造函数仅调用了主构造函数
this(type),完全没有对传入的value参数做任何赋值操作,参数传入后直接被丢弃,实例自然不会保存这个值。 - Kotlin的
data class只有在主构造函数内声明的参数才会被自动识别为类成员属性,参与自动生成的toString、copy、属性存取逻辑。你在次级构造函数里定义的value只是构造过程的临时参数,根本不是类的属性。 - 额外说明:你写的两个次级构造函数在JVM上会因为类型擦除出现签名冲突——
aNode和bNode擦除后都是引用类型,两个构造函数签名完全一致,本身就不满足重载要求,编译阶段就可能报错。
修复方案
把需要存储的value属性放到主构造函数中声明,用aNode和bNode的公共父类型作为属性类型即可,不需要额外写冗余的次级构造函数:
open class parentNode open class aNode: parentNode() open class bNode: parentNode() // 主构造函数直接声明所有需要持久化的属性,给value加默认值兼容只传type的场景 data class Node( var type: String, var value: parentNode? = null ): parentNode()
修改后你原来的节点构造逻辑可以直接正常运行,传入的aNode实例会被正常保存到对象属性中:
fun getNode(): Node { val aNode = aNode() // 替换为你实际获取aNode实例的逻辑 val type = "Bank" return Node(type, aNode) } // 调用后a.value就是你传入的aNode实例,不会丢失 val a = getNode()
如果你需要对不同value类型的构造逻辑做区分,推荐用伴生对象的工厂方法实现,比次级构造函数可读性更强、也不会有签名冲突问题:
data class Node( var type: String, var value: parentNode? = null ): parentNode() { companion object { fun createWithANode(type: String, aValue: aNode): Node { // 可以在这里加aNode场景下的专属初始化逻辑 return Node(type, aValue) } fun createWithBNode(type: String, bValue: bNode): Node { // 可以在这里加bNode场景下的专属初始化逻辑 return Node(type, bValue) } } }
注:类名建议遵循Kotlin编码规范,使用大写开头的大驼峰命名(比如
Node而不是node),避免和变量、方法名混淆。
内容的提问来源于stack exchange,提问作者Helen
相关产品推荐
相关产品推荐

