Kotlin中使用Gson讀取,data class默認(rèn)賦值為空

分享一個(gè)Kotlin搭配Gson的坑

今天發(fā)現(xiàn)服務(wù)端返回的一個(gè)javaBean里面有三個(gè)List<T>其實(shí)是可以合并到一個(gè)List<T>的,所以打算合并一下,遂在javaBean中增加一個(gè)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(){
        //從服務(wù)端獲取
        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

解決方案很簡(jiǎn)單,在mix方法中給mixList賦值
通過(guò)閱讀Gson源碼分析一下
構(gòu)造一個(gè)Person類(lèi)試試

    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;
    ---
  • 可以看到這里通過(guò)TypeAdapter來(lái)讀取字符串,
    通過(guò)斷點(diǎn)來(lái)到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;
  }
  • 看一下這個(gè)raw的來(lái)源
  @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));
  }

也就是我們傳進(jìn)來(lái)要轉(zhuǎn)換的結(jié)果class,gson通過(guò)默認(rèn)構(gòu)造函數(shù)構(gòu)造了一個(gè)Person對(duì)象,通過(guò)遍歷field,并進(jìn)行一一匹配填充,而沒(méi)有讀取到的初始值為空,所以我們?cè)?code>data class中賦的值沒(méi)有意義了~

構(gòu)造器.jpg

log.jpg
  • 看一下Kotlin的構(gòu)造器問(wèn)題
默認(rèn)構(gòu)造.jpg

也就是說(shuō),我們賦的默認(rèn)值失去了意義~
其實(shí)也沒(méi)啥,就是記錄一下

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 在Android開(kāi)發(fā)中,網(wǎng)絡(luò)請(qǐng)求十分常用 而在Android網(wǎng)絡(luò)請(qǐng)求庫(kù)中,Retrofit是當(dāng)下最熱的一個(gè)網(wǎng)...
    053999cbda34閱讀 412評(píng)論 0 0
  • 今天飛哥講了公司職責(zé)介紹和Kotlin 什么是Kotlin? Kotlin,它是JetBrains開(kāi)發(fā)的基于JVM...
    木南_adb3閱讀 225評(píng)論 0 1
  • 前言 之前一段時(shí)間,準(zhǔn)備把糗百的項(xiàng)目中json解析的模塊中的原生Json解析換成gson解析,工作比較繁雜,坑多,...
    拉丁吳閱讀 3,388評(píng)論 9 28
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月,有人笑有人哭,有人歡樂(lè)有人憂愁,有人驚喜有人失落,有的覺(jué)得收獲滿滿有...
    陌忘宇閱讀 8,839評(píng)論 28 54
  • 信任包括信任自己和信任他人 很多時(shí)候,很多事情,失敗、遺憾、錯(cuò)過(guò),源于不自信,不信任他人 覺(jué)得自己做不成,別人做不...
    吳氵晃閱讀 6,367評(píng)論 4 8

友情鏈接更多精彩內(nèi)容