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 super T> 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 super T> 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 super T> rawType) {
try {
final Constructor super T> 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;//返回结果
}