我想使用以下代码反序列化一个json以使用objectmapper映射:
fun onMessage(topic: String, message: MqttMessage) {
val typeRef = object : TypeReference<HashMap<String, String>>() {}
val msg = objectMapper.readValue(message.payload, typeRef)
...
}
Run Code Online (Sandbox Code Playgroud)
编译器表示不会推断参数T in fun <T : Any!> readValue (src: ByteArray!, valueTypeRef: (TypeReference<Any!>..TypeReference<*>?)): T!
如果用我的自定义类扩展HashMap,是否有解决此问题的方法:
class MyHashMap : HashMap<String, String>()
Run Code Online (Sandbox Code Playgroud)
...
fun onMessage(topic: String, message: MqttMessage) {
val msg = objectMapper.readValue(message.payload, MyHashMap::class.java)
...
}
Run Code Online (Sandbox Code Playgroud)
实际上,问题出在杰克逊的API中。这里是如何的readValue方法声明:
public <T> T readValue(String content, TypeReference valueTypeRef)
Run Code Online (Sandbox Code Playgroud)
他们TypeReference出于某种原因使用原始类型,即使可以轻松地将a TypeReference<T>作为其参数。如果这样做的话,您的代码将按原样工作,因为Kotlin然后可以推断T该函数的泛型类型参数,从而知道其返回类型。
但是,可以通过使用类型明确来解决此问题。
通过为函数提供通用类型参数,并msg推断变量的类型:
val msg = objectMapper.readValue<HashMap<String, String>>(message.payload, typeRef)
Run Code Online (Sandbox Code Playgroud)或者,通过显式键入变量并推断出函数的type参数,可以:
val msg: HashMap<String, String> = objectMapper.readValue(message.payload, typeRef)
Run Code Online (Sandbox Code Playgroud)一种可能的方式:
inline fun <reified T> ObjectMapper.readValue(s: String): T = this.readValue(s, object : TypeReference<T>() {})
val msg: Map<String,String> = objectMapper.readValue(message.payload)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1427 次 |
| 最近记录: |