为什么Kotlin Jackson不能反序列化列表

时间:2018-08-31 12:50:03

标签: exception kotlin jackson jvm

我有一个功能:

inline fun <reified T : Any>parse(result: String): T  = mapper.readValue<Response<T>>(result).someValue

当我传递列表类型时,例如List<MyClass>,并尝试从中获取一些物品,但出现以下异常:

Exception in thread "ForkJoinPool.commonPool-worker-3" 
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to MyClass

1 个答案:

答案 0 :(得分:3)

您需要将类型传递给readValue函数,否则Jackson将无法知道应将其转换为哪种类型。默认情况下,杰克逊然后只返回包含键及其值的地图。

因此,对于您的特定问题,您可以只制作parse-function inline并将reified添加到您传递的类型中。这样可以确保将实际类型也传递给Jackson。另请参见reified types in the kotlin reference。另外,您可以传递实际类型(使用TypeReference或类本身(如果不是通用的)。

以前,此答案还包含有关如何将json列表反序列化为实际列表的一般信息,在此我将留作参考:

mapper.readValue(result, object : TypeReference<List<MyClass>>() {})

或者如果您使用jackson-module-kotlin

mapper.readValue<List<MyClass>>(result)

应用于您的函数,如下所示:

inline fun <reified T : Any>parse(result: String): T  = mapper.readValue(result, object : TypeReference<T>() {})

或使用jackson-module-kotlin:

inline fun <reified T : Any>parse(result: String): T  = mapper.readValue(result)

调用它就是:

val yourObjList = parse<List<MyClass>>(yourJson)
// or
val yourObjList : List<MyClass> = parse(yourJson)

请注意,我使用了reified(这意味着inline)。如果您不使用reified,则实际类型不会传递给jackson-module-kotlin的方法化。