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

原理:

参考链接: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字段赋值;如果有默认的无参构造函数,则通过反射调用默认构造函数创建实例。

    原文作者:BugFree张瑞
    原文地址: https://www.jianshu.com/p/497aae1e43d2
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞