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

Kotlin密封接口Bar的子类Foo序列化失败问题求助

Kotlinx序列化密封接口多态序列化异常问题

问题代码

@Serializable
data class Foo
(
   var text: String?
) : Bar

@Serializable
sealed interface Bar {
    var id: String?
    val hash: String
        get() {
            return this.toString().md5()
        }
}

fun save(): Boolean {
    return try {
        this.id = this.hash
        val tmp = Json.encodeToString(this)
        //save the number to Kali datastore.
        Datalayer.save(tmp)
        true
    } catch (e: Exception) {
        false
    }
}

var aa = Foo("woo")
aa.save()

异常信息

kotlinx.serialization.SerializationException: Class 'Foo' is not registered for polymorphic serialization in the scope of 'Bar'.
Mark the base class as 'sealed' or register the serializer explicitly.

异常触发自val tmp = Json.encodeToString(this)行。

依赖配置:

  • 序列化依赖:implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.0")
  • Kotlin插件:kotlin("plugin.serialization") version "1.7.20"

问题原因及解决方案

核心问题1:序列化时未指定基类序列化器

虽然Bar是密封接口,但在save()方法中,this的静态类型为Bar,kotlinx.serialization无法自动推断需要使用基类的多态序列化器,导致无法识别子类Foo。

解决方法:序列化时明确传入Bar.serializer()作为参数:

val tmp = Json.encodeToString(Bar.serializer(), this)

核心问题2:代码结构错误

save()函数被定义在Bar接口外部,无法作为Bar实现类的成员方法调用(除非是扩展函数,但代码中未声明),需将其移至Bar接口内部作为成员函数:

@Serializable
sealed interface Bar {
    // ... 原有属性 ...

    fun save(): Boolean {
        return try {
            this.id = this.hash
            val tmp = Json.encodeToString(Bar.serializer(), this)
            Datalayer.save(tmp)
            true
        } catch (e: Exception) {
            false
        }
    }
}

核心问题3:接口属性未实现

Bar接口定义了var id: String?抽象属性,但Foo类未实现该属性,这会导致编译错误。需修正Foo类:

@Serializable
data class Foo(
    var text: String?,
    override var id: String? // 实现Bar的id属性
) : Bar

若希望所有子类共享id的默认值,可在Bar接口中设置默认值:

@Serializable
sealed interface Bar {
    var id: String? = null
    // ... 其他内容 ...
}

完整修正代码

import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json

@Serializable
data class Foo(
    var text: String?,
    override var id: String?
) : Bar

@Serializable
sealed interface Bar {
    var id: String?
    val hash: String
        get() {
            return this.toString().md5()
        }

    fun save(): Boolean {
        return try {
            this.id = this.hash
            val tmp = Json.encodeToString(Bar.serializer(), this)
            Datalayer.save(tmp)
            true
        } catch (e: Exception) {
            false
        }
    }
}

object Datalayer {
    fun save(data: String) {
        // 实现存储逻辑
    }
}

fun main() {
    val aa = Foo("woo", null)
    aa.save()
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 12:53:23