如何解决Kotlin可序列化密封类中open val重写的序列化冲突?
解决Kotlinx Serialization密封类中open val重写的序列化冲突问题
你碰到的这个错误,核心原因是Kotlinx Serialization会把data class构造函数里的所有属性都当作独立的可序列化字段,而你在子类Theory中用override声明的id,和父类Exercise里的id拥有完全相同的序列化名称,这就触发了重复字段的冲突。
下面给你两种实用的解决办法:
方法一:用@IgnoreSerializing标记子类的重复属性
这个注解可以告诉序列化框架:“忽略子类里的这个id字段,只序列化父类中定义的版本”,完美解决重复问题。代码如下:
import kotlinx.serialization.Serializable import kotlinx.serialization.IgnoreSerializing @Serializable sealed class Exercise(open val id: String) { @Serializable data class Theory(@IgnoreSerializing override val id: String) : Exercise(id) }
⚠️ 注意:@IgnoreSerializing是Kotlinx Serialization 1.4.0及以上版本才有的特性,如果你用的是更早的版本,记得先升级依赖。
方法二:把子类改为普通类,手动实现equals/hashCode
如果你不需要data class自动生成的equals、hashCode等方法,可以把Theory改成普通类,自己实现必要的逻辑。这样一来,子类的id就不会被框架当作独立的序列化字段,自然就不会和父类的字段冲突了:
import kotlinx.serialization.Serializable @Serializable sealed class Exercise(open val id: String) { @Serializable class Theory(override val id: String) : Exercise(id) { override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is Theory) return false return id == other.id } override fun hashCode(): Int = id.hashCode() } }
这两种方法都能解决你的问题,具体选哪种取决于你是否需要保留data class的特性~
内容的提问来源于stack exchange,提问作者Bohdan Yevtushenko
相关产品推荐
相关产品推荐

