Gson 的坑

公司项目中经常要使用json作为数据交换格式,在使用Gson时遇到了一个特别奇怪的问题。debug时,在List中看到是有数据的,转成json后却是null。当时我采用的是下面第一种写法

(二)、    ArrayList常用的初始化方法有三种:

1: List<String> strings=new ArrayList<String>(){{

            add("1");
            add("2");
            add("3");
            add("4");
            add("5");
        }};

      

2:List<String> list= Arrays.asList("a","b","c","d");  //这种方法可以直接把数组转化成list

3:List<String> stringList=new ArrayList<String>();
        for (int i = 0; i < 5; i++) {
            stringList.add(String.valueOf(i));
        }          //这种方法是最常用的一种,循环添加进去


(二)、哪这三种方式有什么不同呢?

          直接上图

           

1、可以看到第一种方式生成的对象实际上并不是一个ArrayList(JsonUtil是该java的文件名),而是当前类(JsonUtil)的一个内部类。

2、同理第二种方式生成的是一个Arrays的内部类对象,该类继承自 abstractList

3、第三种生成的才是我们常用的ArrayList 

(三)、结果

经错查看Gson源码

Gson.java :

      public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOException {
    TypeAdapter<?> adapter = getAdapter(TypeToken.get(typeOfSrc));
    boolean oldLenient = writer.isLenient();
    writer.setLenient(true);
    boolean oldHtmlSafe = writer.isHtmlSafe();
    writer.setHtmlSafe(htmlSafe);
    boolean oldSerializeNulls = writer.getSerializeNulls();
    writer.setSerializeNulls(serializeNulls);
    try {
      ((TypeAdapter<Object>) adapter).write(writer, src);  //这里强转 返回一个匿名内部类,详见下一页源码
    } catch (IOException e) {
      throw new JsonIOException(e);
    } finally {
      writer.setLenient(oldLenient);
      writer.setHtmlSafe(oldHtmlSafe);
      writer.setSerializeNulls(oldSerializeNulls);
    }
  }

Excluder.java
     public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) {
    Class<?> rawType = type.getRawType();
    final boolean skipSerialize = excludeClass(rawType, true);  //转成json为null的原来在这,详见该方法,true
    final boolean skipDeserialize = excludeClass(rawType, false);

    if (!skipSerialize && !skipDeserialize) {
      return null;
    }

    return new TypeAdapter<T>() {
      /** The delegate is lazily created because it may not be needed, and creating it may fail. */
      private TypeAdapter<T> delegate;
    
      @Override public void write(JsonWriter out, T value) throws IOException {
        if (skipSerialize) {  //true
          out.nullValue();   //JsonWrite.write("null")
          return;
        }
        delegate().write(out, value);
      }

      private TypeAdapter<T> delegate() {
        TypeAdapter<T> d = delegate;
        return d != null
            ? d
            : (delegate = gson.getDelegateAdapter(Excluder.this, type));
      }
    };
  }

//排除要跳过的

 public boolean excludeClass(Class<?> clazz, boolean serialize) {
    if (version != Excluder.IGNORE_VERSIONS
        && !isValidVersion(clazz.getAnnotation(Since.class), clazz.getAnnotation(Until.class))) {
      return true;
    }

    if (!serializeInnerClasses && isInnerClass(clazz)) {  //根本原因,跳过了内部类
      return true;
    }

    if (isAnonymousOrLocal(clazz)) {
      return true;
    }

    List<ExclusionStrategy> list = serialize ? serializationStrategies : deserializationStrategies;
    for (ExclusionStrategy exclusionStrategy : list) {
      if (exclusionStrategy.shouldSkipClass(clazz)) {
        return true;
      }
    }

    return false;
  }

 Gson.java

 public String toJson(Object src, Type typeOfSrc) {
    StringWriter writer = new StringWriter();
    toJson(src, typeOfSrc, writer);
    return writer.toString();  //writer=='null'
  }

StringWriter.java

    public String toString() {
        return buf.toString();    //buf=='null'
    }



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值