Gson源码分析(二)

Gson解析后的数据一般不会是String类型,而是Object(的子类)或者Array(广义)类型。先从Object类型说起。
假设需要解析的数据如下

{
"name":"张三",
"others":{"phone":"13888888888",
"address":"北京"}
}

其对应的数据结构为:

public class TestModel {
    String name;
    Others others;

    public static class Others {
        String phone;
        String address;
    }
}

采用Gson的fromJson方法解析如上数据,程序会走到Gson类的getAdapter()方法中

for (TypeAdapterFactory factory : factories) {
        TypeAdapter candidate = factory.create(this, type);
        if (candidate != null) {
          call.setDelegate(candidate);
          typeTokenCache.put(type, candidate);
          return candidate;
        }
      }

通过判断create()方法的返回是否为空,来获取TypeAdapter。查询factories中的所有Factory,可能符合如上解析条件的Factory有两个。

factories.add(ObjectTypeAdapter.FACTORY);
factories.add(new ReflectiveTypeAdapterFactory(
constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory));

先看第一个Factory的create()方法。

@Override public  TypeAdapter create(Gson gson, TypeToken type) {
      if (type.getRawType() == Object.class) {
        return (TypeAdapter) new ObjectTypeAdapter(gson);
      }
      return null;
    }

如果fromJson()方法传入的类的Type是Object.class,就采用ObjectTypeAdapter。很显然,一般情况下不会是Object,而是Object的子类。
ReflectiveTypeAdapterFactory的create()方法如下:

  @Override public  TypeAdapter create(Gson gson, final TypeToken type) {
    Class raw = type.getRawType();

    if (!Object.class.isAssignableFrom(raw)) {
      return null; // it's a primitive!
    }

    ObjectConstructor constructor = constructorConstructor.get(type);
    return new Adapter(constructor, getBoundFields(gson, type, raw));
  }

Class的isAssignableFrom()方法用于判断当前Class与传入的参数的关系是否是相等、子类或者接口。如:

Class1.isAssignableFrom(Class2)   

如果Class2跟Class1相等或者Class1是Class2的父类或者Class1是Class2接口,那就就返回true。
再回到ReflectiveTypeAdapterFactory的create()方法。由于java中所有的类都默认继承自Object(Java 的伪单继承),所以,只要是自定义的类,这里都会返回true。所以所有自定义的Model都会用ReflectiveTypeAdapterFactory生成的TypeAdapter来解析。
在create()方法中,有两个地方需要注意:
1 constructorConstructor.get(type);
2 getBoundFields(gson, type, raw);
先来看constructorConstructor.get(type)。

public  ObjectConstructor get(TypeToken typeToken) {
    final Type type = typeToken.getType();
    final Class rawType = typeToken.getRawType();

    // first try an instance creator

    @SuppressWarnings("unchecked") // types must agree
    final InstanceCreator typeCreator = (InstanceCreator) instanceCreators.get(type);
    if (typeCreator != null) {//instanceCreators初始化的时候为空,所以这里为空
      return new ObjectConstructor() {
        @Override public T construct() {
          return typeCreator.createInstance(type);
        }
      };
    }

    // Next try raw type match for instance creators
    @SuppressWarnings("unchecked") // types must agree
    final InstanceCreator rawTypeCreator =
        (InstanceCreator) instanceCreators.get(rawType);
    if (rawTypeCreator != null) {
      return new ObjectConstructor() {
        @Override public T construct() {
          return rawTypeCreator.createInstance(type);
        }
      };
    }

    //一般这里会返回
    ObjectConstructor defaultConstructor = newDefaultConstructor(rawType);
    if (defaultConstructor != null) {
      return defaultConstructor;
    }

    ObjectConstructor defaultImplementation = newDefaultImplementationConstructor(type, rawType);
    if (defaultImplementation != null) {
      return defaultImplementation;
    }

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


private  ObjectConstructor newDefaultConstructor(Class rawType) {
    try {
      final Constructor constructor = rawType.getDeclaredConstructor();//返回一个无参构造方法
      if (!constructor.isAccessible()) {
        constructor.setAccessible(true);
      }
      return new ObjectConstructor() {
        @SuppressWarnings("unchecked") // T is the same raw type as is requested
        @Override public T construct() {
          try {
            Object[] args = null;
            return (T) constructor.newInstance(args);//生成一个实例,这个实例就是fromJson()的返回数据
          } 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;
    }
  }

接下来看getBoundFields()这个方法。

private Map getBoundFields(Gson context, TypeToken type, Class raw) {
    Map result = new LinkedHashMap();
    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;
        }
        field.setAccessible(true);
        Type fieldType = $Gson$Types.resolve(type.getType(), raw, field.getGenericType());//获取Field的Type
        List fieldNames = getFieldNames(field);//获取Field的名字,包括注解中的名字
        BoundField previous = null;
        //如果没有添加注解名字,fieldNames的size为1
        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
          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()));//获取超类的Type
      raw = type.getRawType();
    }
    return result;
  }

getBoundFields()方法返回的主要就是当前类的属性和属性类型。这些数据就是用于后续Json数据解析的。
createBoundField()这个方法也很重要。

private 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...
    //Field可以自定义解析,实现特殊需求
    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);//获取Gson的TypeAdapter

    final TypeAdapter typeAdapter = mapped;
    //返回了BoundField,注意其write和read方法
    return new 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 {
        Object fieldValue = typeAdapter.read(reader);//读取field的值
        if (fieldValue != null || !isPrimitive) {
          field.set(value, fieldValue);//将值写入到field
        }
      }
      @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
      }
    };
  }

最后看一下ReflectiveTypeAdapterFactory的create()方法返回的TypeAdapter的read()方法。

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

      T instance = constructor.construct();//获取实例

      try {
        in.beginObject();//读取json数据
        while (in.hasNext()) {
          String name = in.nextName();
          BoundField field = boundFields.get(name);
          if (field == null || !field.deserialized) {
            in.skipValue();
          } else {
            field.read(in, instance);//写入Field对应的数据
          }
        }
      } catch (IllegalStateException e) {
        throw new JsonSyntaxException(e);
      } catch (IllegalAccessException e) {
        throw new AssertionError(e);
      }
      in.endObject();
      return instance;//返回结果
    }

你可能感兴趣的:(Gson源码分析(二))