Kotlinx序列化:如何规避反序列化的类型化typeargs?

问题描述

实际上,主要问题仍然是Kotlin中没有可归类的类型化typeargs。但这就是为什么在这种特定情况下令我困扰的原因:

假设您有一个包装器类Wrapper,它包含一个字符串content一个类* type,并可以输出通过解析{{通过调用函数type来按需将1}}作为JSON:

content

我想使用kotlinx.serialization。现在,您可能已经注意到,我之前在“课程”之后如何加星号。原因如下:是的,getobj()必须以某种方式获取目标类,但是如何?

是应该是typearg(因为类型为erausre而无法工作)还是class Wrapper<T>(private val content: String,/*private val type: KClass<*>*/) { fun getobj(): T { // ? } } 引用(因为我需要经过修饰的typearg不能工作)?

据我所知,将通用JSON解码为可序列化的目标类的唯一方法是使用Wrapper,其中KClass是目标类型,{{1} }是JSON字符串。现在,Json.decodeFromString<T>(content)被定义为可进行身份验证(以便可以在运行时处理类型),并且只能用另一个经过身份验证的typearg或实际的类引用填充。我不能使用另一个类型化的typearg,因为我在类的上下文中,并且一个类不能具有类型化的typeargs。我也不能使用实际的类引用,因为该类的用户应该能够使用不同的目标来构造它,例如他们决定目标是什么,而不是我。

那么,我该如何使用kotlinx.serialization?甚至有可能吗?

解决方法

好,所以还没有人回答这个问题,但是我也把这个问题发布在r / Kotlin subreddit中。 Here it is

我实际上在那里找到了答案(对u / JakeWharton的积分),由于您通过Google搜索相同的问题可能会遇到这个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中使用。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...