Gson与Kotlin嵌套的类

我无法正确反序列化嵌套的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

使用@JvmSuppressWildcards注释List似乎有助于:

 var outer: Map<String, @JvmSuppressWildcards List<Entry>>? = null 

如果我们不使用@JvmSuppressWildcards ,那么Kotlin代码被转换为:

 Map<String, ? extends List<TestJsonKotlin.Entry>> outer; 

如果我们使用它,那么代码被翻译成:

 Map<String, List<TestJsonKotlin.Entry>> outer; 

区别在于通配符? extends ? extends – 即使用Java编写,也不支持。 我在这里提交了一个Gson仓库的问题 。


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 case添加? extendsjava.util.List<TestJsonKotlin$Entry> ? extends