Kotlin:具有TypeReference <hashmap <string,string =“” >>的objectmapper.readValue()无法推断参数

时间:2018-09-08 18:26:46

标签: kotlin jackson

我想使用以下代码反序列化一个json以使用objectmapper映射:

fun onMessage(topic: String, message: MqttMessage) {
   val typeRef = object : TypeReference<HashMap<String, String>>() {}
   val msg = objectMapper.readValue(message.payload, typeRef)
   ...
}

编译器表示它无法推断fun <T : Any!> readValue (src: ByteArray!, valueTypeRef: (TypeReference<Any!>..TypeReference<*>?)): T!中的参数T

是否可以通过以下自定义类扩展HashMap来解决此问题?

class MyHashMap : HashMap<String, String>()

...

fun onMessage(topic: String, message: MqttMessage) {
   val msg = objectMapper.readValue(message.payload, MyHashMap::class.java)
   ...
}

2 个答案:

答案 0 :(得分:5)

实际上,问题出在杰克逊的API中。 readValue方法的声明方式如下:

public <T> T readValue(String content, TypeReference valueTypeRef)

出于某种原因,他们使用TypeReference的原始类型,即使他们可以轻松地将TypeReference<T>作为其参数。如果这样做的话,您的代码将按原样工作,因为Kotlin然后可以推断函数的T泛型类型参数,因此知道其返回类型。

但是,可以通过明确使用类型来解决此问题。

  • 通过为函数提供通用类型参数,并推断出msg变量的类型:

    val msg = objectMapper.readValue<HashMap<String, String>>(message.payload, typeRef)
    
  • 或者,通过显式键入变量并推断出函数的type参数:

    val msg: HashMap<String, String> = objectMapper.readValue(message.payload, typeRef)
    

答案 1 :(得分:0)

一种可能的方式:

inline fun <reified T> ObjectMapper.readValue(s: String): T = this.readValue(s, object : TypeReference<T>() {})

val msg: Map<String,String> = objectMapper.readValue(message.payload)