Gson解析后的數(shù)據(jù)一般不會(huì)是String類型,而是Object(的子類)或者Array(廣義)類型。先從Object類型說(shuō)起。
假設(shè)需要解析的數(shù)據(jù)如下
{
"name":"張三",
"others":{"phone":"13888888888",
"address":"北京"}
}
其對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)為:
public class TestModel {
String name;
Others others;
public static class Others {
String phone;
String address;
}
}
采用Gson的fromJson方法解析如上數(shù)據(jù),程序會(huì)走到Gson類的getAdapter()方法中
for (TypeAdapterFactory factory : factories) {
TypeAdapter<T> candidate = factory.create(this, type);
if (candidate != null) {
call.setDelegate(candidate);
typeTokenCache.put(type, candidate);
return candidate;
}
}
通過(guò)判斷create()方法的返回是否為空,來(lái)獲取TypeAdapter。查詢factories中的所有Factory,可能符合如上解析條件的Factory有兩個(gè)。
factories.add(ObjectTypeAdapter.FACTORY);
factories.add(new ReflectiveTypeAdapterFactory(
constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory));
先看第一個(gè)Factory的create()方法。
@Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
if (type.getRawType() == Object.class) {
return (TypeAdapter<T>) new ObjectTypeAdapter(gson);
}
return null;
}
如果fromJson()方法傳入的類的Type是Object.class,就采用ObjectTypeAdapter。很顯然,一般情況下不會(huì)是Object,而是Object的子類。
ReflectiveTypeAdapterFactory的create()方法如下:
@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!
}
ObjectConstructor<T> constructor = constructorConstructor.get(type);
return new Adapter<T>(constructor, getBoundFields(gson, type, raw));
}
Class的isAssignableFrom()方法用于判斷當(dāng)前Class與傳入的參數(shù)的關(guān)系是否是相等、子類或者接口。如:
Class1.isAssignableFrom(Class2)
如果Class2跟Class1相等或者Class1是Class2的父類或者Class1是Class2接口,那就就返回true。
再回到ReflectiveTypeAdapterFactory的create()方法。由于java中所有的類都默認(rèn)繼承自O(shè)bject(Java 的偽單繼承),所以,只要是自定義的類,這里都會(huì)返回true。所以所有自定義的Model都會(huì)用ReflectiveTypeAdapterFactory生成的TypeAdapter來(lái)解析。
在create()方法中,有兩個(gè)地方需要注意:
1 constructorConstructor.get(type);
2 getBoundFields(gson, type, raw);
先來(lái)看constructorConstructor.get(type)。
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) {//instanceCreators初始化的時(shí)候?yàn)榭?,所以這里為空
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);
}
};
}
//一般這里會(huì)返回
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);
}
private <T> ObjectConstructor<T> newDefaultConstructor(Class<? super T> rawType) {
try {
final Constructor<? super T> constructor = rawType.getDeclaredConstructor();//返回一個(gè)無(wú)參構(gòu)造方法
if (!constructor.isAccessible()) {
constructor.setAccessible(true);
}
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);//生成一個(gè)實(shí)例,這個(gè)實(shí)例就是fromJson()的返回?cái)?shù)據(jù)
} 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;
}
}
接下來(lái)看getBoundFields()這個(gè)方法。
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) {
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<String> fieldNames = getFieldNames(field);//獲取Field的名字,包括注解中的名字
BoundField previous = null;
//如果沒(méi)有添加注解名字,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);//創(chuàng)建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()方法返回的主要就是當(dāng)前類的屬性和屬性類型。這些數(shù)據(jù)就是用于后續(xù)Json數(shù)據(jù)解析的。
createBoundField()這個(gè)方法也很重要。
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可以自定義解析,實(shí)現(xiàn)特殊需求
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();//獲取實(shí)例
try {
in.beginObject();//讀取json數(shù)據(jù)
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對(duì)應(yīng)的數(shù)據(jù)
}
}
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
in.endObject();
return instance;//返回結(jié)果
}