当使用Gson将JSONMap转换为Kotlin/JavaMap,并且JSON值包含"[]"
形式的数组时,如果声明并访问Array<T>
,则会出现ClassCastException
错误。(Array<T>
等效于Java数组T[]
):
应用程序/构建.gradle:
dependencies {
...
implementation 'com.google.code.gson:gson:2.8.6'
}
jsonConverter.kt(使用this guide):
@Throws(JsonSyntaxException::class)
fun gsonMapTest() {
val jsonInput = """
{"keyOne":[],"keyTwo":["valueA"],"keyThree":[]}
""".trimIndent()
// Guidance: https://www.baeldung.com/gson-json-to-map
val jsonMap1 = Gson().fromJson<LinkedTreeMap<String, Array<String>>>(jsonInput, MutableMap::class.java)
val jsonMap2: Map<*,*> = Gson().fromJson(jsonInput, Map::class.java) // MutableMap can also be used
// These work fine
val firstKeyInMap1: String = jsonMap1.keys.first() // returns String
val firstKeyInMap2 = jsonMap2.keys.first() // returns String
// Errors here: "java.lang.ClassCastException: java.util.ArrayList cannot be cast to [Ljava.lang.String;"
val firstValueInMap1: Array<String> = jsonMap1.values.first()
val firstValueInMap2: Array<String> = jsonMap2.values.first() as Array<String>
}
此错误发生在运行时:
java.lang.ClassCastException: java.util.ArrayList cannot be cast to [Ljava.lang.String;
但是Map对象被允许创建,没有任何警告或错误,只有当访问Map值时才会发生错误。
从错误消息中,我最初认为对jsonMap1.values.first()
的调用是试图将空数组转换为String。
如果代码示例中的声明从Array<String>
更改为ArrayList<String>
,则一切正常。
"我的问题是"
- Gson允许
Array<T>
声明,但在访问项时会导致错误,这是正常的行为吗? - 有没有办法显示警告或编译错误,说明应该使用
ArrayList<String>
而不是Array<String>
?
我检查了Gson的Github问题。我没有发现这个问题,但我发现了一些稍微相似的问题:
- https://github.com/google/gson/issues/105--抛出类转换异常而不是分析错误
- https://github.com/google/gson/issues/1107-- Gson将通配符反序列化为LinkedHashMap
- https://github.com/google/gson/issues/1247--令人困惑的异常
更新:也许这是同样的问题?:Java gson, ClassCastException on decoding to Map<String,String[]>
1条答案
按热度按时间evrscar21#
正如用户 fluffy 在他/她的评论中提到的,除了泛型描述之外,还必须使用
TypeToken
来反序列化参数化泛型类型。但是,ArrayList<String>
似乎不需要这样做: