Kotlin泛型Processor类序列化@Serializable类型的优化方案咨询
解决Kotlin Serialization泛型父类序列化问题
针对你遇到的泛型父类无法直接调用encodeToString的问题,除了显式传递序列化器之外,还有几种更简洁的实现方式:
方案1:抽象属性简化子类实现
将序列化器定义为父类的抽象属性,子类仅需重写该属性返回对应类型的序列化器,比构造传参更直观:
package com.renault.rclib import kotlinx.serialization.Serializable import kotlinx.serialization.SerializationStrategy import kotlinx.serialization.json.Json import kotlinx.serialization.serializer abstract class Processor<T : Any> { protected abstract val serializer: SerializationStrategy<T> protected fun process(data: T) { val json = Json.encodeToString(serializer, data) println(json) } } @Serializable data class Foo(val f: Int) class FooProcessor : Processor<Foo>() { override val serializer = Foo.serializer() fun doSomething() { process(getFooFromSomewhere()) } private fun getFooFromSomewhere() = Foo(17) } fun main() { FooProcessor().doSomething() }
方案2:通过KClass缓存序列化器
让父类接收KClass<T>,初始化时一次性获取并缓存序列化器,子类只需传入Class对象:
package com.renault.rclib import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json import kotlinx.serialization.serializer import kotlin.reflect.KClass abstract class Processor<T : Any>(private val clazz: KClass<T>) { private val serializer = serializer(clazz.createType()) protected fun process(data: T) { val json = Json.encodeToString(serializer, data) println(json) } } @Serializable data class Foo(val f: Int) class FooProcessor : Processor<Foo>(Foo::class) { fun doSomething() { process(getFooFromSomewhere()) } private fun getFooFromSomewhere() = Foo(17) } fun main() { FooProcessor().doSomething() }
方案3:inline+reified泛型快速创建实例
如果子类不需要扩展额外逻辑,可通过父类伴生对象的inline函数自动推导类型并生成序列化器,无需手动实现子类:
package com.renault.rclib import kotlinx.serialization.Serializable import kotlinx.serialization.SerializationStrategy import kotlinx.serialization.json.Json import kotlinx.serialization.serializer abstract class Processor<T : Any> { protected abstract val serializer: SerializationStrategy<T> protected fun process(data: T) { val json = Json.encodeToString(serializer, data) println(json) } companion object { inline fun <reified T : Any> create(): Processor<T> { return object : Processor<T>() { override val serializer = T.serializer() } } } } @Serializable data class Foo(val f: Int) fun main() { val processor = Processor.create<Foo>() processor.process(Foo(17)) }
关于“黑魔法”方案的性能说明
你提到的通过serializer(data::class.createType())获取序列化器的方案,不会每次创建新实例——Kotlin Serialization内部会缓存序列化器,多次调用只会复用已有对象,性能开销极小。只要你的T是标注@Serializable的具体非泛型类,这个方案完全可用,代码也是最简洁的:
abstract class Processor<T : Any> { protected fun process(data: T) { val serializer = serializer(data::class.createType()) val json = Json.encodeToString(serializer, data) println(json) } }
内容的提问来源于stack exchange,提问作者wujek
相关产品推荐
相关产品推荐

