Kotlin Gson定制解串器列表

Mam*_*rey 6 java android json gson kotlin

如何在Gson中注册自定义Json反序列化器?

当我在java代码中注册反序列化器时一切正常,但是当我将Kotlin转换为Java时 - 没有调用deserializer方法.

Kotlin注册码:

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

val retrofit = Retrofit.Builder()
               .addConverterFactory(GsonConverterFactory.create(gson))
Run Code Online (Sandbox Code Playgroud)

Java代码:

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

Retrofit retrofit = new Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create(gson))
Run Code Online (Sandbox Code Playgroud)

反序列化器声明:

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

方法调用

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

据我所知 - Json对象的类型问题(listType),或者我做错了什么?

Mih*_*x64 14

问题是Kotlin编译器添加了一个通配符List,即List<out T>编译为List<CharSequence>.

解决方案是要么使用 List<? extends Charsequence>

object : TypeToken<MutableList<Advert>>() {}.type
Run Code Online (Sandbox Code Playgroud)

或supperss通配符

object : TypeToken<List<@JvmSuppressWildcards Advert>>() {}.type
Run Code Online (Sandbox Code Playgroud)