json - Kotlinx 序列化 : How to circumvent reified typeargs for deserialization?

标签 json kotlin generics kotlinx.serialization kotlin-reified-type-parameters

实际上,主要问题仍然是 Kotlin 中的类没有具体化的类型参数。但这就是为什么在这种特定情况下这困扰我的原因:
假设您有一个包装类 Wrapper接受一个字符串 content和一个类(class)* type并且可以输出类 type 的对象通过解析检索content通过调用函数 getObj() 按需作为 JSON :

class Wrapper<T>(private val content: String, /*private val type: KClass<*>*/) {
    fun getObj(): T {
        // ?
    }
}
我想使用 kotlinx.serialization。现在,您可能已经注意到我之前是如何在“class”之后加上星号的。原因如下:是的,Wrapper必须以某种方式接受目标类(class),但如何?它应该只是 typearg(因为类型erausre 不起作用)还是KClass引用(不起作用,因为我需要一个具体化的 typearg)?
事情是,据我所知,将通用 JSON 解码为可序列化目标类的唯一方法是使用 Json.decodeFromString<T>(content) ,其中 T是目标类型和 content是 JSON 字符串。现在,T被定义为具体化(以便可以在运行时处理该类型)并且只能填充另一个具体化的 typearg 或实际的类引用。我不能使用另一个具体化的 typearg,因为我在一个类的上下文中,而一个类不能有具体化的 typeargs。我也不能使用实际的类引用,因为类的用户应该能够用不同的目标来构造它,例如他们决定目标是什么,而不是我。
那么,我如何使用 kotlinx.serialization 做到这一点?甚至有可能吗?

最佳答案

好的,所以还没有人回答这个问题,但我也在 r/Kotlin subreddit 中发布了这个问题。 Here it is .
我实际上在那里得到了一个答案(归功于 u/JakeWharton),并且由于您可能会遇到这个 StackOverflow 问题,因为您在谷歌上搜索了相同的问题,因此您可能很高兴在这里找到答案。所以这是我试图解释答案的尝试:
因此,基本上,kotlinx 序列化确实不适用于 KClass es.但仔细想想,你只需要KClass以确定如何序列化它。由于这是在您使用 KXS 时在编译时确定的,因此您实际上只需要传递序列化程序(定义如何序列化/反序列化您的类的实际策略)。您可以获得每个用 @Serializable 注释的类的序列化程序。通过调用 .serializer()在上面;结果将是类型 KSerializer<T> .所以,而不是拥有

class Wrapper<T>(private val content: String, private val type: KClass<T>)
并通过构建它
val wrapper = Wrapper("{}", Foo::class)
你可以这样做:
class Wrapper<T>(private val content: String, private val serializer: KSerializer<T>)
然后像这样构造它:
val wrapper = Wrapper("{}", Foo.serializer())
(假设 Foo@Serializable 注释)
然后您可以使用 KSerializer 序列化和反序列化而不是 typearg,像这样:
val obj: T = Json.decodeFromString(serializer, "[Your JSON String]")
val str: String = Json.encodeToString(serializer, obj)
就是这样!只需换掉您的常规 (K)Class方法来自 KSerializer它将与 KXS 一起使用。

关于json - Kotlinx 序列化 : How to circumvent reified typeargs for deserialization?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64155561/

相关文章:

Android kotlin MVVM - 你可以在 recyclerview 适配器中调用 viewmodel 吗?

java - 为什么通用 "factory"创建的类型与来自相同内联代码的类型不同?

ios - 如何在 Swift 中从加密的 JSON 字符串中提取某些字段?

javascript - 图像不生成 D3

当对象包含 'init' 时,Java 反射初始化 Kotlin 对象失败

android - 如何在 Android Studio 中找到最新版本的 Kotlin

scala - 添加和扩展通用编写器特征以进行逐步数据存储的最佳方法

java - 引用内部泛型类型

php - 如何在 symfony2 Controller 中发送 JSON 响应

java - 如何在 Gson 反序列化中折叠嵌套结构?