美文网首页Android 开发
使用Gson反序列化时导致实体类的默认值失效

使用Gson反序列化时导致实体类的默认值失效

作者: BugFree张瑞 | 来源:发表于2018-12-04 14:45 被阅读22次

    原理:

    参考链接:https://blog.csdn.net/z69183787/article/details/52556609

    GSON是通过什么样的方式创建MyObj对象的呢?

    GSON是使用ObjectConstructor来创建对象实例的,这点从代码注释里也能看的出来

    /**
     * Defines a generic object construction factory.  The purpose of this class
     * is to construct a default instance of a class that can be used for object
     * navigation while deserialization from its JSON representation.
     *
     * @author Inderjeet Singh
     * @author Joel Leitch
     */
    public interface ObjectConstructor<T> {
    
      /**
       * Returns a new instance.
       */
      public T construct();
    }
    

    那么ObjectConstructor从何而来呢?答案在ConstructorConstructor里:

    public <T> ObjectConstructor<T> get(TypeToken<T> typeToken) {
      final Type type = typeToken.getType();
      final Class<? super T> rawType = typeToken.getRawType();
    
      // first try an instance creator
    
      @SuppressWarnings("unchecked") // types must agree
      final InstanceCreator<T> typeCreator = (InstanceCreator<T>) instanceCreators.get(type);
      if (typeCreator != null) {
        return new ObjectConstructor<T>() {
          @Override public T construct() {
            return typeCreator.createInstance(type);
          }
        };
      }
    
      // Next try raw type match for instance creators
      @SuppressWarnings("unchecked") // types must agree
      final InstanceCreator<T> rawTypeCreator =
          (InstanceCreator<T>) instanceCreators.get(rawType);
      if (rawTypeCreator != null) {
        return new ObjectConstructor<T>() {
          @Override public T construct() {
            return rawTypeCreator.createInstance(type);
          }
        };
      }
    
      ObjectConstructor<T> defaultConstructor = newDefaultConstructor(rawType);
      if (defaultConstructor != null) {
        return defaultConstructor;
      }
    
      ObjectConstructor<T> defaultImplementation = newDefaultImplementationConstructor(type, rawType);
      if (defaultImplementation != null) {
        return defaultImplementation;
      }
    
      // finally try unsafe
      return newUnsafeAllocator(type, rawType);
    }
    
    1. 如果我们(通过GsonBuilder)注册过InstanceCreator,则交给InstanceCreator来创建实例
    2. 如果类有默认构造函数,则通过反射调用默认构造函数创建实例
    3. 如果想要创建List或Map等接口的实例,则走这里
    4. 否则交给神秘的UnsafeAllocator来收场

    结论:

    反序列化时,如果一个类没有默认构造函数,那么GSON是通过JDK内部API来创建对象实例的,并且通过反射给final字段赋值;如果有默认的无参构造函数,则通过反射调用默认构造函数创建实例。

    相关文章

      网友评论

        本文标题:使用Gson反序列化时导致实体类的默认值失效

        本文链接:https://www.haomeiwen.com/subject/udwmcqtx.html