1

I have a generic class class MyClass<T> : MyInterface<T> and I want to deserialize a json to generic type T. I tried using Jackson and kotlinx.serialization libraries to deserialize json but I get following error

cannot use T as reified type parameter. Use class instead.

My understanding of why this is happening is because both Jackson and kotlinx deserialize function expect reified T but in my class there is no way to know the type of T at compile time. Is my understanding of this error correct? Is there any way to resolve this error?

My code snippet

class MyClass<T> : MyInterface<T>{
    .... <some code> ...
    
    fun readFromJson(json: String){
        val obj = jacksonObjectMapper().readValue<T>(json)
        // same error if I use kotlinx Json.decodeFromString<T>(json)
        ...
    }
    .... <some code> ...
}
sap
  • 75
  • 1
  • 1
  • 10

1 Answers1

1

My understanding of why this is happening is because both Jackson and kotlinx deserialize function expect reified T but in my class there is no way to know the type of T at compile time. Is my understanding of this error correct?

Correct.

Is there any way to resolve this error?

It depends on what you're trying to do with the T in question. The best would be to lift readFromJson() out of this class, to a place where T can actually be reified.

If you really do need this function to be present in your class (e.g. you need to access some internal state or something), then you'll have to pass a KClass<T>/Class<T> (for Jackson) or a DeserializationStrategy<T> (for Kotlinx serialization) to the constructor of your class, so that you can use the non-reified overloads of readValue() or decodeFromString() which take this extra info as parameter.

Joffrey
  • 32,348
  • 6
  • 68
  • 100
  • All Jackson kotlin implementations use reified types - https://github.com/FasterXML/jackson-module-kotlin/blob/8ecd701d44421265ca864300277087a68978d92d/src/main/kotlin/com/fasterxml/jackson/module/kotlin/Extensions.kt I was unable to find any example that use KClass. I will keep searching but if you know of any such example, can you point me to it? – sap May 16 '21 at 15:06
  • @sap there are plenty of overloads of `readValue` that take a `Class` parameter, such as [this one](https://fasterxml.github.io/jackson-databind/javadoc/2.7/com/fasterxml/jackson/databind/ObjectMapper.html#readValue(java.lang.String,%20java.lang.Class)) (these are basic jackson methods, not extensions from the kotlin module). – Joffrey May 17 '21 at 02:26
  • @sap for Kotlinx serialization, you have [decodeFromString](https://kotlin.github.io/kotlinx.serialization/kotlinx-serialization-json/kotlinx-serialization-json/kotlinx.serialization.json/-json/decode-from-string.html) that takes a `DeserializationStrategy` – Joffrey May 17 '21 at 02:32
  • thank you so much for these code pointers. I will try to rewrite my code using these methods. – sap May 17 '21 at 03:20