谈谈我对Gson源码的理解

1 MainActivity.kt

data class Person(val name: String,val age: Int)

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val person = Gson().fromJson("{"name":"gerry","age":18}", Person::class.java)
    }

}

2 Gson.java

public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException {
  Object object = fromJson(json, (Type) classOfT);
  return Primitives.wrap(classOfT).cast(object);
}


  public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException {
    if (json == null) {
      return null;
    }
    StringReader reader = new StringReader(json);
    T target = (T) fromJson(reader, typeOfT);
    return target;
  }


  public <T> T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException {
    JsonReader jsonReader = newJsonReader(json);
    T object = (T) fromJson(jsonReader, typeOfT);
    assertFullConsumption(object, jsonReader);
    return object;
  }


  public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
      //  ... 省略其他代码
       TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);
      // 第一步 getAdapter 获取适配器
      TypeAdapter<T> typeAdapter = getAdapter(typeToken);
      // 第二步 read 创建对象并给对象赋值
      T object = typeAdapter.read(reader);
      // 第三步返回对象
      return object;
  }

3 getAdapter 获取适配器

public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {
     // .....  这里省略了一些读缓存的重要代码,具体见目录5的介绍
  
      // 3.1 这个 factories是什么?
      for (TypeAdapterFactory factory : factories) {
         // 3.2 这个 factory.create 如何创建的?
        TypeAdapter<T> candidate = factory.create(this, type);
        if (candidate != null) {
          // call 其实是 candidate 的代理类 
          call.setDelegate(candidate);
          typeTokenCache.put(type, candidate);
          return candidate;
        }
      }
  
     // ..... 
  }

3.1 这个 factories是什么?

是一个 TypeAdapterFactory 集合,在Gson创建时就被添加了各种Factory,具体如下图所示

   final List<TypeAdapterFactory> factories;
    
   // 下面开始添加各种  TypeAdapterFactory
   List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();

    // built-in type adapters that cannot be overridden
    factories.add(TypeAdapters.JSON_ELEMENT_FACTORY);
    factories.add(ObjectTypeAdapter.FACTORY);

    // the excluder must precede all adapters that handle user-defined types
    factories.add(excluder);

    // users' type adapters 如果我们有自定义的 TypeAdapterFactory 会在这里被提前添加,为什么会这么靠前?
    // 因为遍历集合时会首先找到自定义的TypeAdapterFactory
    factories.addAll(factoriesToBeAdded);

    // type adapters for basic platform types
    factories.add(TypeAdapters.STRING_FACTORY);
    factories.add(TypeAdapters.INTEGER_FACTORY);
    factories.add(TypeAdapters.BOOLEAN_FACTORY);
    factories.add(TypeAdapters.BYTE_FACTORY);
    factories.add(TypeAdapters.SHORT_FACTORY);
    TypeAdapter<Number> longAdapter = longAdapter(longSerializationPolicy);
    factories.add(TypeAdapters.newFactory(long.class, Long.class, longAdapter));
    factories.add(TypeAdapters.newFactory(double.class, Double.class,
            doubleAdapter(serializeSpecialFloatingPointValues)));
    factories.add(TypeAdapters.newFactory(float.class, Float.class,
            floatAdapter(serializeSpecialFloatingPointValues)));
    factories.add(TypeAdapters.NUMBER_FACTORY);
    factories.add(TypeAdapters.ATOMIC_INTEGER_FACTORY);
    factories.add(TypeAdapters.ATOMIC_BOOLEAN_FACTORY);
    factories.add(TypeAdapters.newFactory(AtomicLong.class, atomicLongAdapter(longAdapter)));
    factories.add(TypeAdapters.newFactory(AtomicLongArray.class, atomicLongArrayAdapter(longAdapter)));
    factories.add(TypeAdapters.ATOMIC_INTEGER_ARRAY_FACTORY);
    factories.add(TypeAdapters.CHARACTER_FACTORY);
    factories.add(TypeAdapters.STRING_BUILDER_FACTORY);
    factories.add(TypeAdapters.STRING_BUFFER_FACTORY);
    factories.add(TypeAdapters.newFactory(BigDecimal.class, TypeAdapters.BIG_DECIMAL));
    factories.add(TypeAdapters.newFactory(BigInteger.class, TypeAdapters.BIG_INTEGER));
    factories.add(TypeAdapters.URL_FACTORY);
    factories.add(TypeAdapters.URI_FACTORY);
    factories.add(TypeAdapters.UUID_FACTORY);
    factories.add(TypeAdapters.CURRENCY_FACTORY);
    factories.add(TypeAdapters.LOCALE_FACTORY);
    factories.add(TypeAdapters.INET_ADDRESS_FACTORY);
    factories.add(TypeAdapters.BIT_SET_FACTORY);
    factories.add(DateTypeAdapter.FACTORY);
    factories.add(TypeAdapters.CALENDAR_FACTORY);
    factories.add(TimeTypeAdapter.FACTORY);
    factories.add(SqlDateTypeAdapter.FACTORY);
    factories.add(TypeAdapters.TIMESTAMP_FACTORY);
    factories.add(ArrayTypeAdapter.FACTORY);
    factories.add(TypeAdapters.CLASS_FACTORY);

    // type adapters for composite and user-defined types
    factories.add(new CollectionTypeAdapterFactory(constructorConstructor));
    factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization));
    this.jsonAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor);
    factories.add(jsonAdapterFactory);
    factories.add(TypeAdapters.ENUM_FACTORY);
    // 核心工厂类! 我们自定义的类(例如本例的 Person) 都是靠这个ReflectiveTypeAdapterFactory创建
    // constructorConstructor 是 Gson成员变量 类型是 ConstructorConstructor.java
    factories.add(new ReflectiveTypeAdapterFactory(
        constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory));
   
    this.factories = Collections.unmodifiableList(factories);

3.2 这个 factory.create 如何创建的?

我们知道了factory.create 中的 factory 其实是 ReflectiveTypeAdapterFactory.java

@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!
  }
  // 3.3 ObjectConstructor是什么?
  ObjectConstructor<T> constructor = constructorConstructor.get(type);
  // 3.4 getBoundFields 是什么?
  // 返回的是 ReflectiveTypeAdapterFactory.java 中的 静态内部类 Adapter
  return new Adapter<T>(constructor, getBoundFields(gson, type, raw));
}

3.3 ObjectConstructor是什么?

由3.1知道 constructorConstructor 是 Gson成员变量 类型是 ConstructorConstructor.java

通过调用 construct() 方法反射创建无参对象 (这里搞明白了对象是怎么创建的)

public <T> ObjectConstructor<T> get(TypeToken<T> typeToken) {
    final Type type = typeToken.getType();
    final Class<? super T> rawType = typeToken.getRawType();

    // instanceCreators 默认为空Map,因此省略相关代码 ....
  
    //  newDefaultConstructor 创建普通的对象,重点要看这个
    ObjectConstructor<T> defaultConstructor = newDefaultConstructor(rawType);
    if (defaultConstructor != null) {
      return defaultConstructor;
    }

    // newDefaultImplementationConstructor创建 Map and List and their subtypes
    ObjectConstructor<T> defaultImplementation = newDefaultImplementationConstructor(type, rawType);
    if (defaultImplementation != null) {
      return defaultImplementation;
    }

    // finally try unsafe
    return newUnsafeAllocator(type, rawType);
  }


private <T> ObjectConstructor<T> newDefaultConstructor(Class<? super T> rawType) {
    try {
      final Constructor<? super T> constructor = rawType.getDeclaredConstructor();
      if (!constructor.isAccessible()) {
        accessor.makeAccessible(constructor);
      }
      return new ObjectConstructor<T>() {
        @SuppressWarnings("unchecked") // T is the same raw type as is requested
        @Override public T construct() {
          try {
            Object[] args = null;
            // 在这里我们看到了熟悉的反射创建对象
            return (T) constructor.newInstance(args);
          } catch (InstantiationException e) {
            // TODO: JsonParseException ?
            throw new RuntimeException("Failed to invoke " + constructor + " with no args", e);
          } catch (InvocationTargetException e) {
            // TODO: don't wrap if cause is unchecked!
            // TODO: JsonParseException ?
            throw new RuntimeException("Failed to invoke " + constructor + " with no args",
                e.getTargetException());
          } catch (IllegalAccessException e) {
            throw new AssertionError(e);
          }
        }
      };
    } catch (NoSuchMethodException e) {
      return null;
    }
  }

3.4 getBoundFields 是什么?

返回的是一个Map,其中key是字段名(或别名),value是 ReflectiveTypeAdapterFactory.BoundField

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) {
    // 先找此类的所有字段(public protected private 但不包括父类的字段)
    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());
      // 为什么你给变量设置别名也能被识别成功? @SerializedName 
      // 为什么根据一个 field能获取一个集合?   @SerializedName(value = "height", alternate = {"Height", "mHeight"})
      // 因为考虑到了多种属性名对应一种字段的情况
      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
        // 4.1   createBoundField 是什么? 
        BoundField boundField = createBoundField(context, field, name,
            TypeToken.get(fieldType), serialize, deserialize);
        // 如果之前没有存过这个field 则返回为null,否则返回非null
        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;
}

这段代码是使用反射来解析一个类的字段,并创建相应的 BoundField 对象,然后将这些对象存储在一个 LinkedHashMap<String, BoundField> 中。这个映射的键是字段的名称,值是与字段相关联的 BoundField 对象。

具体步骤如下:

  1. 创建一个空的 LinkedHashMap,用于存储字段名和对应的 BoundField 对象。

  2. 如果给定的类是一个接口,直接返回空的映射,因为接口一般不包含实例字段。

  3. 获取类的类型信息,然后进入一个循环,该循环会遍历当前类及其父类的所有字段。

  4. 对于每个字段,通过一些条件判断确定是否需要进行序列化(serialize)和反序列化(deserialize)。

  5. 使用反射使字段可访问,并获取其类型信息。

  6. 获取字段名列表,因为一个字段可能有多个名字(通过注解等方式指定)。

  7. 遍历字段名列表,为每个名字创建一个 BoundField 对象,然后将该对象添加到映射中。

  8. 如果同一个字段有多个名字,则会抛出 IllegalArgumentException

  9. 更新当前类的类型信息为其父类的类型信息,以便迭代到父类的字段。

  10. 重复上述步骤,直到达到 Object 类为止。

  11. 返回最终的字段映射。

4 read 创建对象并给对象赋值

根据 3.2 返回的是 ReflectiveTypeAdapterFactory.java 中的 静态内部类 Adapter

@Override public T read(JsonReader in) throws IOException {
  if (in.peek() == JsonToken.NULL) {
    in.nextNull();
    return null;
  }

  // 毫不意外调用了 3.3 中的construct()反射创建无参对象
  T instance = constructor.construct();

  try {
    in.beginObject();
    while (in.hasNext()) {
      String name = in.nextName();
      BoundField field = boundFields.get(name);
      if (field == null || !field.deserialized) {
        in.skipValue();
      } else {
        // 遍历每一个字段,然后执行BoundField.read方法给字段赋值
        field.read(in, instance);
      }
    }
  } catch (IllegalStateException e) {
    throw new JsonSyntaxException(e);
  } catch (IllegalAccessException e) {
    throw new AssertionError(e);
  }
  in.endObject();
  return instance;
}

4.1 createBoundField 是什么?

ReflectiveTypeAdapterFactory.BoundField

private ReflectiveTypeAdapterFactory.BoundField createBoundField(
      final Gson context, final Field field, final String name,
      final TypeToken<?> fieldType, boolean serialize, boolean deserialize) {
  
    final boolean isPrimitive = Primitives.isPrimitive(fieldType.getRawType());
    // special casing primitives here saves ~5% on Android...
    // 在这里你可以使用 JsonAdapter注解自定义 TypeAdapter
    JsonAdapter annotation = field.getAnnotation(JsonAdapter.class);
    TypeAdapter<?> mapped = null;
    if (annotation != null) {
      mapped = jsonAdapterFactory.getTypeAdapter(
          constructorConstructor, context, fieldType, annotation);
    }
    final boolean jsonAdapterPresent = mapped != null;
    if (mapped == null) mapped = context.getAdapter(fieldType);
    
    // 这里注意下,我们本身就是在找Person类的getAdapter,如果Person中某个字段也是Person类怎么办?
    // 岂不是会陷入嵌套调用? 3 getAdapter 获取适配器中的 calls 就是解决这个问题的
    if (mapped == null) mapped = context.getAdapter(fieldType);

    final TypeAdapter<?> typeAdapter = mapped;
    return new ReflectiveTypeAdapterFactory.BoundField(name, serialize, deserialize) {
      @SuppressWarnings({"unchecked", "rawtypes"}) // the type adapter and field type always agree
      @Override void write(JsonWriter writer, Object value)
          throws IOException, IllegalAccessException {
        Object fieldValue = field.get(value);
        TypeAdapter t = jsonAdapterPresent ? typeAdapter
            : new TypeAdapterRuntimeTypeWrapper(context, typeAdapter, fieldType.getType());
        t.write(writer, fieldValue);
      }
      @Override void read(JsonReader reader, Object value)
          throws IOException, IllegalAccessException {
           // 核心在这里,  4.2  typeAdapter.read(reader)
        Object fieldValue = typeAdapter.read(reader);
        if (fieldValue != null || !isPrimitive) {
          field.set(value, fieldValue);
        }
      }
      @Override public boolean writeField(Object value) throws IOException, IllegalAccessException {
        if (!serialized) return false;
        Object fieldValue = field.get(value);
        return fieldValue != value; // avoid recursion for example for Throwable.cause
      }
    };
  }

4.2 typeAdapter.read 如何工作?

根据3.4 所示 其实每个字段都对应一个 BoundField

  • 假设现在有个字段是 name:String, 根据 4.1的 context.getAdapter(fieldType) 和 3.1 的 factories.add(TypeAdapters.STRING_FACTORY)
  public static final TypeAdapterFactory STRING_FACTORY = newFactory(String.class, STRING);

  public static final TypeAdapter<String> STRING = new TypeAdapter<String>() {
    @Override
    public String read(JsonReader in) throws IOException {
      JsonToken peek = in.peek();
      if (peek == JsonToken.NULL) {
        in.nextNull();
        return null;
      }
      /* coerce booleans to strings for backwards compatibility */
      if (peek == JsonToken.BOOLEAN) {
        return Boolean.toString(in.nextBoolean());
      }
      return in.nextString();
    }
    @Override
    public void write(JsonWriter out, String value) throws IOException {
      out.value(value);
    }
  };
  • 假设现在有个字段是 age:Int, 根据 4.1的 context.getAdapter(fieldType) 和 3.1 的 factories.add(TypeAdapters.INTEGER_FACTORY)
public static final TypeAdapter<Number> INTEGER = new TypeAdapter<Number>() {
    @Override
    public Number read(JsonReader in) throws IOException {
      if (in.peek() == JsonToken.NULL) {
        in.nextNull();
        return null;
      }
      try {
        return in.nextInt();
      } catch (NumberFormatException e) {
        throw new JsonSyntaxException(e);
      }
    }
    @Override
    public void write(JsonWriter out, Number value) throws IOException {
      out.value(value);
    }
  };

5 时序图总结

Gson ReflectiveTypeAdapterFactory.Adapter ObjectConstructor BoundField TypeAdapter fromJson() 可能存在递归调用栈溢出的地方 getAdapter() getBoundFields() 获取该类所有字段 createBoundField() 每个字段去找自己的getAdapter() read() construct() 反射创建对象 遍历每个字段调用 read() 赋值 每个BoundField对应的TypeAdapter处理 read() Gson ReflectiveTypeAdapterFactory.Adapter ObjectConstructor BoundField TypeAdapter

注意蓝色区域,这里有可能存在递归调用的风险, 我们来举例说明

public class Student{
   private int age;
   private String name;
   private Student friend; // 有一个同类型的属性
}

如源码和上图所示,

  • 第一次对 Student类 getAdapter 时 factory.create遍历其字段发现了 friend字段也是Student类
  • 第二次对 Student类 getAdapter 时 factory.create遍历其字段发现了又发现了 friend字段也是Student类
  • 第三次对 Student类 getAdapter 时 factory.create遍历其字段发现了又发现了 friend字段也是Student类
  • … 重复上述步骤造成递归调用

Gson是如何解决这种问题的呢 ? 缓存 + 代理

public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {
   // 第一层缓存
    //typeTokenCache 是 Gson内部的成员变量 (类型 ConcurrentHashMap<TypeToken<?>, TypeAdapter<?>>())
    TypeAdapter<?> cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type);
    if (cached != null) {
      return (TypeAdapter<T>) cached;
    }

  // 第二层缓存   以防线程不安全,这里使用了ThreadLocal
  // calls 是 Gson内部的成员变量 (类型 ThreadLocal<Map<TypeToken<?>, FutureTypeAdapter<?>>>) 用来防止递归调用 getAdapter 
    Map<TypeToken<?>, FutureTypeAdapter<?>> threadCalls = calls.get();
    boolean requiresThreadLocalCleanup = false;
    if (threadCalls == null) {
      threadCalls = new HashMap<TypeToken<?>, FutureTypeAdapter<?>>();
      calls.set(threadCalls);
      requiresThreadLocalCleanup = true;
    }

    // the key and value type parameters always agree
    // 如果之前已经找到了Student类的adapter就直接使用缓存  FutureTypeAdapter, 只要不调用 factory.create就不会遍历字段了
    FutureTypeAdapter<T> ongoingCall = (FutureTypeAdapter<T>) threadCalls.get(type);
    if (ongoingCall != null) {
      return ongoingCall;
    }

    try {
      FutureTypeAdapter<T> call = new FutureTypeAdapter<T>();
      // 放入threadCalls 缓存
      threadCalls.put(type, call);

     
      for (TypeAdapterFactory factory : factories) {
        // 遍历该类的所有字段,找对应的Adapter
        TypeAdapter<T> candidate = factory.create(this, type);
        if (candidate != null) {
           // 后续同类型直接可以根据 FutureTypeAdapter.delegate来处理
          call.setDelegate(candidate);
          typeTokenCache.put(type, candidate);
          return candidate;
        }
      }
      throw new IllegalArgumentException("GSON (" + GsonBuildConfig.VERSION + ") cannot handle " + type);
    } finally {
      threadCalls.remove(type);

      if (requiresThreadLocalCleanup) {
        calls.remove();
      }
    }
  }
 static class FutureTypeAdapter<T> extends TypeAdapter<T> {
    private TypeAdapter<T> delegate;

    public void setDelegate(TypeAdapter<T> typeAdapter) {
      if (delegate != null) {
        throw new AssertionError();
      }
      delegate = typeAdapter;
    }

    @Override public T read(JsonReader in) throws IOException {
      if (delegate == null) {
        throw new IllegalStateException();
      }
      // FutureTypeAdapter 本质上是代理类,还是使用Adapter来read字段
      return delegate.read(in);
    }

    @Override public void write(JsonWriter out, T value) throws IOException {
      if (delegate == null) {
        throw new IllegalStateException();
      }
      delegate.write(out, value);
    }
  }

至此就把 Json -> Object的过程详细梳理了一遍, Object -> Json 也是类似,只不过把read方法换成了wirte方法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值