繁体   English   中英

Kotlin:带有 TypeReference 的 objectmapper.readValue() <HashMap<String, String> &gt; 无法推断参数

[英]Kotlin: objectmapper.readValue() with TypeReference<HashMap<String, String>> cannot infer parameter

我想使用以下代码将 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!

有没有解决这个问题的方法,不用像这样使用我的自定义类扩展 HashMap:

class MyHashMap : HashMap<String, String>()

...

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

实际上,问题出在 Jackson 的 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)
  • 或者,通过显式键入变量,并推断函数的类型参数:

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

一种可能的方式:

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

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

您可以使用对象表达式来传递TypeReference的匿名实现:

objectMapper.readValue(message.payload, object: TypeReference<HashMap<String, String>>() {})

注意TypeReference参数之前的object:关键字。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM