Kotlin reified issue with parameterized type

Viewed 158

Why does the following not work? It seems that the type Foo is not passed properly, or is this just a well known "issue"?

Foo<T> fails

data class Foo<T>(val a: T)
data class Bar(val b: String)
val objectMapper = ObjectMapper().registerKotlinModule()
val jsonString = "{\"a\": { \"b\": \"str\" }}"
fun main() {
    val parseJson = parseJson<Bar>()
}
private inline fun <reified T> parseJson(): T {
    val readValue: Foo<T> = objectMapper.readValue(jsonString)
    return readValue.a
}
class java.util.LinkedHashMap cannot be cast to class ..Bar 
(java.util.LinkedHashMap is in module java.base of loader 'bootstrap'; 
..Bar is in unnamed module of loader 'app')
1 Answers

The issue in this case is that you're not specifying the class that ObjectMapper should try and map your jsonString to. The matter is further complicated by the Foo type being parametric.

You need to build a JavaType reference to pass to objectMapper.readValue.

private inline fun <reified T> parseJson(): T {
    val javaType = objectMapper.typeFactory.constructParametricType(Foo::class.java, T::class.java)
    val readValue: Foo<T> = objectMapper.readValue(jsonString, javaType)
    return readValue.a
}
Related