Kotlin Gson custom deserializer for list

Mamykin Andrey :

How to register custom Json deserializer in Gson?

When I'm register deserializer in java code all works fine, but when I convert Kotlin to Java - deserializer method not called.

Kotlin register code:

val listType: Type = object : TypeToken<List<Advert>>() {}.type
val gson = GsonBuilder()
           .registerTypeAdapter(listType, deserializer)

val retrofit = Retrofit.Builder()
               .addConverterFactory(GsonConverterFactory.create(gson))

Java code:

Type listType = new TypeToken<List<Advert>>() {}.getType();
Gson gson = new GsonBuilder()
            .registerTypeAdapter(listType, deserializer)

Retrofit retrofit = new Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create(gson))

Deserializer declaration:

class AdvertsDeserializer : JsonDeserializer<List<Advert>> {
override fun deserialize(json: JsonElement?, typeOfT: Type?,
                         context: JsonDeserializationContext?): List<Advert> {

Method calling

// list is List<Advert>
service.getAdverts()
            .subscribe({
                list ->
                viewState.showAdvertsList(list)
            }, {
                error ->
                error.printStackTrace()
            })

As I understand - problem in type of Json object(listType), or what I'm doing wrong?

Miha_x64 :

The problem is that Kotlin compiler sees List like a covariant generic type List<out T> and compiles its instantiations as wildcard types, i. e. List<CharSequence> gets compiled as List<? extends Charsequence>.

The solution is either to use MutableList which is invatiant

object : TypeToken<MutableList<Advert>>() {}.type

or to supperss wildcard generation

object : TypeToken<List<@JvmSuppressWildcards Advert>>() {}.type

More info: Kotlin Generics. Variance

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=464522&siteId=1