Как десериализовать json в общий тип в Kotlin с помощью Jackson / kotlinx.serialization

У меня есть общий класс class MyClass<T> : MyInterface<T>, и я хочу десериализовать json до общего типа T. Я пробовал использовать библиотеки Jackson и kotlinx.serialization для десериализации json, но получаю следующую ошибку

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

Я понимаю, почему это происходит, потому что и функция десериализации Джексона и kotlinx ожидают reified T, но в моем классе нет способа узнать тип T во время компиляции. Правильно ли я понимаю эту ошибку? Есть ли способ исправить эту ошибку?

Мой фрагмент кода

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> ...
}

person sap    schedule 15.05.2021    source источник


Ответы (1)


Я понимаю, почему это происходит, потому что и функция десериализации Джексона и kotlinx ожидают reified T, но в моем классе нет способа узнать тип T во время компиляции. Правильно ли я понимаю эту ошибку?

Верный.

Есть ли способ исправить эту ошибку?

Это зависит от того, что вы пытаетесь сделать с рассматриваемым T. Лучше всего было бы поднять readFromJson() из этого класса до места, где T действительно может быть реифицируемым.

Если вам действительно нужно, чтобы эта функция присутствовала в вашем классе (например, вам нужно получить доступ к некоторому внутреннему состоянию или чему-то еще), вам нужно будет передать _4 _ / _ 5_ (для Джексона) или DeserializationStrategy<T> (для сериализации Kotlinx) в конструктор вашего класса, чтобы вы могли использовать нереализованные перегрузки readValue() или _ 8_, которые принимают эту дополнительную информацию как параметр.

person Joffrey    schedule 15.05.2021
comment
Все реализации котлина Джексона используют овеществленные типы - github.com/FasterXML/jackson-module-kotlin/blob/ Мне не удалось найти ни одного примера, использующего KClass ‹T›. Я буду продолжать поиск, но если вы знаете какой-либо такой пример, можете ли вы указать мне на него? - person sap; 16.05.2021
comment
@sap существует множество перегрузок readValue, которые принимают параметр Class<T>, например this one (это базовые методы Джексона, а не расширения модуля kotlin). - person Joffrey; 17.05.2021
comment
@sap для сериализации Kotlinx, у вас есть decodeFromString, который принимает DeserializationStrategy<T> - person Joffrey; 17.05.2021
comment
Большое вам спасибо за эти указатели кода. Я попробую переписать свой код этими методами. - person sap; 17.05.2021