Kotlin中使用Gson读取,data class默认赋值为空

分享一个Kotlin搭配Gson的坑

今天发现服务端返回的一个javaBean里面有三个List<T>其实是可以合并到一个List<T>的,所以打算合并一下,遂在javaBean中增加一个field

改之前

    data class Example(
        @SerializedName("a_list") val aList : List<String>,
        @SerializedName("b_list") val bList : List<String>,
        @SerializedName("c_list") val cList : List<String>
    )

改之后

    data class Example(
        @SerializedName("a_list") val aList : List<String>,
        @SerializedName("b_list") val bList : List<String>,
        @SerializedName("c_list") val cList : List<String>,
        val mixList: MutableList<String> = arrayListOf()
    )
    fun mix(){
        //从服务端获取
        val example = getExampleData()
        example.mixList.apply {
            addAll(example.aList)
            addAll(example.bList)
            addAll(example.cList)
        }
    }
    fun getExampleData() : Example{
        return Gson().fromJson(getData(),Example::class.java)
    }

然后抛出了mixList的NullPointException

解决方案很简单,在mix方法中给mixList赋值
通过阅读Gson源码分析一下
构造一个Person类试试

    data class Person(
        val name : String,
        val age : Int,
        val job : String = "coder"
    )
  • 首先是fromJson
public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
    ---
      TypeToken<T> typeToken = (TypeToken<T>)   TypeToken.get(typeOfT);
      TypeAdapter<T> typeAdapter = getAdapter(typeToken);
      T object = typeAdapter.read(reader);
      return object;
    ---
  • 可以看到这里通过TypeAdapter来读取字符串,
    通过断点来到ReflectiveTypeAdapterFactorygetBoundFields方法,
private Map<String, BoundField> getBoundFields(Gson context, TypeToken<?> type, Class<?> raw) {
    Map<String, BoundField> result = new LinkedHashMap<String, BoundField>();
    if (raw.isInterface()) {
      return result;
    }

    Type declaredType = type.getType();
    while (raw != Object.class) {
      Field[] fields = raw.getDeclaredFields();
      for (Field field : fields) {
        boolean serialize = excludeField(field, true);
        boolean deserialize = excludeField(field, false);
        if (!serialize && !deserialize) {
          continue;
        }
        accessor.makeAccessible(field);
        Type fieldType = $Gson$Types.resolve(type.getType(), raw, field.getGenericType());
        List<String> fieldNames = getFieldNames(field);
        BoundField previous = null;
        for (int i = 0, size = fieldNames.size(); i < size; ++i) {
          String name = fieldNames.get(i);
          if (i != 0) serialize = false; // only serialize the default name
          BoundField boundField = createBoundField(context, field, name,
              TypeToken.get(fieldType), serialize, deserialize);
          BoundField replaced = result.put(name, boundField);
          if (previous == null) previous = replaced;
        }
        if (previous != null) {
          throw new IllegalArgumentException(declaredType
              + " declares multiple JSON fields named " + previous.name);
        }
      }
      type = TypeToken.get($Gson$Types.resolve(type.getType(), raw, raw.getGenericSuperclass()));
      raw = type.getRawType();
    }
    return result;
  }
  • 看一下这个raw的来源
  @Override public <T> TypeAdapter<T> create(Gson gson, final TypeToken<T> type) {
    Class<? super T> raw = type.getRawType();

    if (!Object.class.isAssignableFrom(raw)) {
      return null; // it's a primitive!
    }

    ObjectConstructor<T> constructor = constructorConstructor.get(type);
    return new Adapter<T>(constructor, getBoundFields(gson, type, raw));
  }

也就是我们传进来要转换的结果class,gson通过默认构造函数构造了一个Person对象,通过遍历field,并进行一一匹配填充,而没有读取到的初始值为空,所以我们在data class中赋的值没有意义了~

构造器.jpg

log.jpg
  • 看一下Kotlin的构造器问题
默认构造.jpg

也就是说,我们赋的默认值失去了意义~
其实也没啥,就是记录一下

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 前言 在Android开发中,网络请求十分常用 而在Android网络请求库中,Retrofit是当下最热的一个网...
    053999cbda34阅读 413评论 0 0
  • 今天飞哥讲了公司职责介绍和Kotlin 什么是Kotlin? Kotlin,它是JetBrains开发的基于JVM...
    木南_adb3阅读 227评论 0 1
  • 前言 之前一段时间,准备把糗百的项目中json解析的模块中的原生Json解析换成gson解析,工作比较繁杂,坑多,...
    拉丁吴阅读 3,393评论 9 28
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,896评论 28 54
  • 信任包括信任自己和信任他人 很多时候,很多事情,失败、遗憾、错过,源于不自信,不信任他人 觉得自己做不成,别人做不...
    吴氵晃阅读 6,391评论 4 8

友情链接更多精彩内容