我无法正确地将嵌套的Kotlin类反序列化为Gson的正确类型。 当我尝试反序列化相同的Java类时,它工作正常。
Java类:
package example;
import java.util.List;
import java.util.Map;
class TestJsonJava {
Map<String, List<Entry>> outer;
static class Entry {
String inner;
}
}
Kotlin课程:
package example
class TestJsonKotlin {
var outer: Map<String, List<Entry>>? = null
class Entry {
var inner: String? = null
}
}
Kotlin主要:
package example
import com.google.gson.GsonBuilder
class Main {
companion object {
@JvmStatic
fun main(args: Array<String>) {
val json = """
{
"outer": {
"keyA": [
{
"inner": "hello"
}
]
}
}
"""
val javaObject = GsonBuilder().create().fromJson(json, TestJsonJava::class.java)
val javaWorks = javaObject.outer!!["keyA"]!![0] is TestJsonJava.Entry
println("Java works : $javaWorks")
println(javaObject.outer!!["keyA"]!![0].inner)
val kotlinObject = GsonBuilder().create().fromJson(json, TestJsonKotlin::class.java)
val kotlinWorks = kotlinObject.outer!!["keyA"]!![0] is TestJsonKotlin.Entry
println("Kotlin works: $kotlinWorks")
println(kotlinObject.outer!!["keyA"]!![0].inner)
}
}
}
打印:
Java works : true
hello
Kotlin works: false
Exception in thread "main" java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to example.TestJsonKotlin$Entry
at example.Main$Companion.main(TestJsonmain.kt:28)
at example.Main.main(TestJsonmain.kt)
如何告诉gson将keyA
的值反序列化为List<Entry>
而不是LinkedTreeMap
?
答案 0 :(得分:4)
使用List
注释@JvmSuppressWildcards
似乎有所帮助:
var outer: Map<String, @JvmSuppressWildcards List<Entry>>? = null
如果我们不使用@JvmSuppressWildcards
,那么Kotlin代码将转换为:
Map<String, ? extends List<TestJsonKotlin.Entry>> outer;
如果我们使用它,那么代码将转换为:
Map<String, List<TestJsonKotlin.Entry>> outer;
区别在于通配符? extends
- 即使您用Java编写它也不支持。我在Gson的存储库here中提交了一个问题。
javap
突出显示两种情况之间的区别:
// `TestJsonKotlin` with `val outer` is compiled to
public final class TestJsonKotlin {
private final java.util.Map<java.lang.String, java.util.List<TestJsonKotlin$Entry>> outer;
public final java.util.Map<java.lang.String, java.util.List<TestJsonKotlin$Entry>> getOuter();
// ...
}
// `TestJsonKotlin` with `var outer` is compiled to
public final class TestJsonKotlin {
private java.util.Map<java.lang.String, ? extends java.util.List<TestJsonKotlin$Entry>> outer;
public final java.util.Map<java.lang.String, java.util.List<TestJsonKotlin$Entry>> getOuter();
// ...
}
var
案例会在? extends
前面添加java.util.List<TestJsonKotlin$Entry>
。