使用 KClass 引用作为具体化参数从 JSON 反序列化
Using a KClass reference as a reified parameter to deserialize from JSON
我正在尝试实现一个通用序列化框架,以使用 kotlinx 序列化将传出和传入消息转换为 json。我正在开发一个多平台应用程序,所以我试图在 KotlinJVM 和 KotlinJS 上将其添加到 运行。
为此,我向每条消息添加一个 type
字段,并使用映射将每个 type
字符串映射到 KClass
。该地图的类型是什么?它包含 KClass<>
个对象,其 classes 扩展了消息 class,因此在 java 中我将我的地图指定为
Map<KClass<? extends Message>, String>
.
我如何在 Kotlin 中做到这一点?
之后,我需要根据消息的键和类型对消息进行序列化和反序列化。 Java 框架采用 Class 参数作为我想要 deserialize/instantiate 的对象类型(例如 gson.fromJson(ClientMessage.class)
)。在 Kotlin 中,这是使用 reified
参数 Json.decodeFromString<Type>
完成的。我在编译时不知道消息的类型,只是有一个对 KClass
的引用,我如何根据它实例化一个对象?
@Serializable
open class Message(val type: String) {
companion object {
val messageTypes: Map<KClass<out Message>, String> = mapOf(
ClientLoginMessage::class to "clientLoginMessage",
Message::class to "message"
)
inline fun <reified T> getMessageTypeByClass(): String = messageTypes[T::class]!! // utility for defining the type in the constructors of the individual messages
}
fun toJson() = Json.encodeToString(this)
fun fromJson(json: String): Message? {
val plainMessage = Json.decodeFromString<Message>(json) // get type string from json
return messageTypes.entries.find { it.value == plainMessage.type }?.let {
// how can I use the KClass from it.key as reified parameter?
Json.decodeFromString<?????>(json)
}
}
}
@Serializable
class ClientLoginMessage
: Message(Message.getMessageTypeByClass<ClientLoginMessage>()) {}
像类型一样创建序列化器映射:
val serializers: Map<KClass<out Message>, KSerializer<out Message>> = mapOf(
ClientLoginMessage::class to ClientLoginMessage.serializer(),
Message::class to Message.serializer()
)
像这样传入 Json.decodeFromString
所需的序列化程序:
fun fromJson(json: String): Message? {
val plainMessage = Json.decodeFromString<Message>(json) // get type string from json
return messageTypes.entries.find { it.value == plainMessage.type }?.let {
// how can I use the KClass from it.key as reified parameter?
Json.decodeFromString(serializers.get(plainMessage.type)!!, json)
}
}
您可能还想看看 Kotlin 内置的多态处理 类:https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md
我正在尝试实现一个通用序列化框架,以使用 kotlinx 序列化将传出和传入消息转换为 json。我正在开发一个多平台应用程序,所以我试图在 KotlinJVM 和 KotlinJS 上将其添加到 运行。
为此,我向每条消息添加一个 type
字段,并使用映射将每个 type
字符串映射到 KClass
。该地图的类型是什么?它包含 KClass<>
个对象,其 classes 扩展了消息 class,因此在 java 中我将我的地图指定为
Map<KClass<? extends Message>, String>
.
我如何在 Kotlin 中做到这一点?
之后,我需要根据消息的键和类型对消息进行序列化和反序列化。 Java 框架采用 Class 参数作为我想要 deserialize/instantiate 的对象类型(例如 gson.fromJson(ClientMessage.class)
)。在 Kotlin 中,这是使用 reified
参数 Json.decodeFromString<Type>
完成的。我在编译时不知道消息的类型,只是有一个对 KClass
的引用,我如何根据它实例化一个对象?
@Serializable
open class Message(val type: String) {
companion object {
val messageTypes: Map<KClass<out Message>, String> = mapOf(
ClientLoginMessage::class to "clientLoginMessage",
Message::class to "message"
)
inline fun <reified T> getMessageTypeByClass(): String = messageTypes[T::class]!! // utility for defining the type in the constructors of the individual messages
}
fun toJson() = Json.encodeToString(this)
fun fromJson(json: String): Message? {
val plainMessage = Json.decodeFromString<Message>(json) // get type string from json
return messageTypes.entries.find { it.value == plainMessage.type }?.let {
// how can I use the KClass from it.key as reified parameter?
Json.decodeFromString<?????>(json)
}
}
}
@Serializable
class ClientLoginMessage
: Message(Message.getMessageTypeByClass<ClientLoginMessage>()) {}
像类型一样创建序列化器映射:
val serializers: Map<KClass<out Message>, KSerializer<out Message>> = mapOf(
ClientLoginMessage::class to ClientLoginMessage.serializer(),
Message::class to Message.serializer()
)
像这样传入 Json.decodeFromString
所需的序列化程序:
fun fromJson(json: String): Message? {
val plainMessage = Json.decodeFromString<Message>(json) // get type string from json
return messageTypes.entries.find { it.value == plainMessage.type }?.let {
// how can I use the KClass from it.key as reified parameter?
Json.decodeFromString(serializers.get(plainMessage.type)!!, json)
}
}
您可能还想看看 Kotlin 内置的多态处理 类:https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md