大家好,我有以下代码,用于序列化为 json 字符串以存储在共享首选项中
interface Serializer {
public fun <T> serialize(data: T, type: Class<T>): String
public fun <T> deserialize(source: String, type: Class<T>): T?
}
我稍后可以创建此类的实现并使用 Moshi 序列化我的对象,如下所示
class SerializerImpl(
private val moshi: Moshi = Moshi.Builder()
.build(),
) : Serializer {
override fun <T> deserialize(source: String, type: Class<T>): T? = try {
moshi.adapter(type).fromJson(source)
} catch (exception: Exception) {
null
}
override fun <T> serialize(data: T, type: Class<T>): String =
moshi.adapter(type).toJson(data)
}
您能否建议如何迁移此实现以使用 kotlinx 序列化,而不必更改 Serializer 接口的签名似乎我必须更改 Serializer 接口的类型以使用 KSerializer 才能使其正常工作,但我真的很想避免这种情况。
Kotlinx.serialization 为动态创建序列化器提供实验性支持,从提供的
Type
或 KType
:
class KotlinxSerializer : Serializer {
override fun <T> serialize(data: T, type: Class<T>) = Json.encodeToString(type.serializer(), data)
override fun <T> deserialize(source: String, type: Class<T>) = Json.decodeFromString(type.serializer(), source)
}
@OptIn(ExperimentalSerializationApi::class)
@Suppress("UNCHECKED_CAST")
private fun <T> Class<T>.serializer(): KSerializer<T> = Json.serializersModule.serializer(this) as KSerializer<T>
用途:
fun main() {
val ser = KotlinxSerializer()
val d1 = MyData("hello")
val s = ser.serialize(d1, MyData::class.java)
println(s) // {"foo":"hello"}
val d2 = ser.deserialize(s, MyData::class.java)
println(d2) // MyData(foo=hello)
}
@Serializable
data class MyData(val foo: String)
请注意,我们仍然需要用
@Serializable
标记所有数据类。如果没有这个,Kotlinx.serialization 就无法工作,因为这是一个编译时序列化框架。