Kotlin中如何使用Gson反序列化包含抽象类属性的JSON数据
Kotlin 反序列化包含抽象泛型类的JSON实现方案
可以实现,核心逻辑是通过类型标识字段将抽象类映射到对应的可实例化子类,同时处理泛型类型擦除问题,常用两种实现方案如下:
方案1:使用kotlinx.serialization(Kotlin官方序列化库)
步骤1:给抽象类和子类添加序列化注解
通过类鉴别器字段区分不同子类实现:
import kotlinx.serialization.* import kotlinx.serialization.json.JsonClassDiscriminator @Serializable @JsonClassDiscriminator("account_type") // JSON中用于区分子类的字段名 abstract class Account<T> { abstract val id: String abstract val accountData: T } // 普通账户子类示例 @Serializable @SerialName("regular") // 对应account_type字段值为regular时匹配该类 data class RegularAccount( override val id: String, override val accountData: RegularData, val balance: Long ) : Account<RegularData>() // 信用卡账户子类示例 @Serializable @SerialName("credit") // 对应account_type字段值为credit时匹配该类 data class CreditAccount( override val id: String, override val accountData: CreditData, val creditLimit: Long ) : Account<CreditData>()
步骤2:修改数据类注解
@Serializable data class User( // 符合Kotlin命名规范首字母大写 val name: String, val accounts: List<Account<*>> // 泛型边界可根据实际业务调整 )
步骤3:执行反序列化
val jsonStr: String = // 你的JSON字符串 val user = Json.decodeFromString<User>(jsonStr)
方案2:使用Jackson
步骤1:给抽象类添加子类映射注解
import com.fasterxml.jackson.annotation.JsonTypeInfo import com.fasterxml.jackson.annotation.JsonSubTypes @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "account_type" ) @JsonSubTypes( JsonSubTypes.Type(value = RegularAccount::class, name = "regular"), JsonSubTypes.Type(value = CreditAccount::class, name = "credit") ) abstract class Account<T> { abstract val id: String abstract val accountData: T }
步骤2:执行反序列化
通过TypeReference规避泛型擦除问题:
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.KotlinModule import com.fasterxml.jackson.module.kotlin.readValue val objectMapper = ObjectMapper() .registerModule(KotlinModule.Builder().build()) val jsonStr: String = // 你的JSON字符串 val user: User = objectMapper.readValue(jsonStr)
注意事项
- 如果你的JSON结构中没有专门的类型区分字段,可以自定义反序列化器,根据JSON字段特征匹配对应子类
- 抽象类的所有子类、泛型参数对应的类都需要满足所选序列化库的序列化要求
- 建议将原数据类
user重命名为User,符合Kotlin类名大驼峰命名规范
内容的提问来源于stack exchange,提问作者Nan Li
相关产品推荐
相关产品推荐

