1.fromJson
public T fromJson(String json, Class classOfT) throws JsonSyntaxException {
Object object = fromJson(json, (Type) classOfT);
return Primitives.wrap(classOfT).cast(object);
}
这个方法的实现,是调用了传入Type的fromJson
public 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;
}
这里调用的fromJson是传入了一个Reader对象
public T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException {
JsonReader jsonReader = newJsonReader(json);
T object = (T) fromJson(jsonReader, typeOfT);
assertFullConsumption(object, jsonReader);
return object;
}
这里调用的fromJson是传入了JsonReader对象,所有的fromJson都会调用下面这个
public T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
boolean isEmpty = true;
boolean oldLenient = reader.isLenient();
reader.setLenient(true);
try {
reader.peek();
isEmpty = false;
// 将传入的Type实例封装成一个TypeToken实例
TypeToken typeToken = (TypeToken) TypeToken.get(typeOfT);
// 根据对应的TypeToken,从typeTokenCache这个Map缓存中取出对应的TypeAdapter
TypeAdapter typeAdapter = getAdapter(typeToken);
// 调用对应的TypeAdapter的实现类的read方法,将对应的JsonReader封装Json字符串之后的对象解析转换成对应的实体类
T object = typeAdapter.read(reader);
return object;
} catch (EOFException e) {
/*
* For compatibility with JSON 1.5 and earlier, we return null for empty
* documents instead of throwing.
*/
if (isEmpty) {
return null;
}
throw new JsonSyntaxException(e);
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
} catch (IOException e) {
// TODO(inder): Figure out whether it is indeed right to rethrow this as JsonSyntaxException
throw new JsonSyntaxException(e);
} finally {
reader.setLenient(oldLenient);
}
}
在这里,是通过TypeAdapter对象获取到了返回的Object对象,而TypeAdapter是通过getAdapter方法得到的:
@SuppressWarnings("unchecked")
public TypeAdapter getAdapter(TypeToken type) {
// 1.首先尝试从Gson中的Map缓存中取出对应的TypeAdapter实现类对象
TypeAdapter> cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type);
if (cached != null) {
return (TypeAdapter) cached;
}
// 2.
// calls是一个Gson内部的ThreadLocal对象,是一个ThreadLocal
上面getAdapter代码中会遍历存储TypeAdapterFactory的factories,寻找对应的TypeAdapterFactory实例,比如返回一个Bean类的对象的话,则会调用ReflectiveTypeAdapterFactory,通过这个Factory.create创建对应的TypeAdapter实例。
2.属性说明
private final ThreadLocal
calls是一个ThreadLocal,这个ThreadLocal缓存了一个Map集合,通过对应的TypeToken在当前线程中取出对应的FutureTypeAdapter,然后返回。增加一个ThreadLocal缓存的目的就是为了避免递归查找导致无限创建TypeAdapter实例而出现栈溢出。
比如:
public class Article {
public Article article;
.....
.....
.....
}
在这个例子中,一个Article,其内部有一个属性,也是Article类型的,如果不使用ThreadLocal,那么就会出现无限递归创建对应的TypeAdapter实例进行解析。而使用委托类,则会通过委托类对象,其内部调用已经创建的TypeAdapter进行read。这样就会复用同一个TypeAdapter实例。
可以参考下面的文章中的内容:
https://www.jianshu.com/p/aef252db9869
3.ReflectiveTypeAdapterFactory.BoundField相关
在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);
// 调用ReflectiveTypeAdapterFactory.getBoundFields方法返回一个Map集合,
// 这个Map集合的key其实就是Field的name,而BoundField其实就是根据对应的字段类型、字段名称等进行封装委托
return new Adapter(constructor, getBoundFields(gson, type, raw));
}
private Map getBoundFields(Gson context, TypeToken> type, Class> raw) {
Map result = new LinkedHashMap();
if (raw.isInterface()) {
return result;
}
Type declaredType = type.getType();
// 如果真实类型是Object类型,则结束循环
while (raw != Object.class) {
// 获取该类型的所有内部属性,getDeclaredFields()方法是获取本类型,不包括父类的所有属性(包括私有属性)
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());
// 获取字段名称,因为通过Gson注解可以给一个字段设置多个name
List 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
// 创建BoundField
BoundField boundField = createBoundField(context, field, name,
TypeToken.get(fieldType), serialize, deserialize);
// 替换Map中已有的value
BoundField replaced = result.put(name, boundField);
if (previous == null) previous = replaced;
}
if (previous != null) {
// 如果previous不为null,说明Map中在根据name创建BoundField的时候,已经有一个BoundField
// 这样的情况说明一个name有了两个BoundField,则说明一个类中出现两个字段名相同的字段
throw new IllegalArgumentException(declaredType
+ " declares multiple JSON fields named " + previous.name);
}
}
type = TypeToken.get($Gson$Types.resolve(type.getType(), raw, raw.getGenericSuperclass()));
// 获取父类型,继续循环,直到父类型为Object为止。
// 这样做的目的就是为了Bean类有继承的情况,能对父类属性进行解析。
raw = type.getRawType();
}
return result;
}
在通过ReflectiveTypeAdapterFactory.create创建TypeAdapter实例的时候,通过getBoundFields创建一个Map集合,主要就是为了对类的所有属性进行封装。
// 根据Field创建BoundField,并且封装Field的读写操作
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 annotation = field.getAnnotation(JsonAdapter.class);
TypeAdapter> mapped = null;
if (annotation != null) {
mapped = jsonAdapterFactory.getTypeAdapter(
constructorConstructor, context, fieldType, annotation);
}
final boolean jsonAdapterPresent = mapped != null;
// Gson尝试获取该Field字段类型的TypeAdapter
// 这里的context其实就是Gson实例,这里其实又是调用了Gson.getAdapter
if (mapped == null) mapped = context.getAdapter(fieldType);
// 使用final,是便于内部类使用
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);
}
// 执行Json数据的读取解析操作,然后转换成Object对象,通过Field.set,给对应的字段设置value值。
@Override void read(JsonReader reader, Object value)
throws IOException, IllegalAccessException {
// 通过该属性的类型对应的TypeAdapter尝试读取json串
//如果是基础类型,则直接读取,
//如果是复合类型则递归之前的流程
// 因为在Gson.fromJson方法中,最终就是通过调用typeAdapter.read进行json串解析
// 而这里是又被typeAdapter.read调用,而这里又调用了typeAdapter.read(reader);
// 其实就是一个递归调用流程,即在typeAdapter.read内部调用了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.ReflectiveTypeAdapterFactory.read
找到对应的TypeAdapter之后,就会调用对应的read方法。以反射方式实现为例子:
主要是借助了ReflectiveTypeAdapterFactory,每个TypeAdapter其实都是通过对应的Factory的create方法获取到的。而ReflectiveTypeAdapterFactory中有一个内部类,就是继承了TypeAdapter类
public static final class Adapter extends TypeAdapter {
// 用于反射获取对象
private final ObjectConstructor constructor;
private final Map boundFields;
Adapter(ObjectConstructor constructor, Map boundFields) {
this.constructor = constructor;
this.boundFields = boundFields;
}
@Override public T read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
T instance = constructor.construct();
try {
in.beginObject();
while (in.hasNext()) {
String name = in.nextName();
BoundField field = boundFields.get(name);
// 判断boundFields中对应的字段名称是否为空,如果为空则跳过
// 这就是为什么json串中有更多字段的数据,可以使用更少属性的类来解析,因为这里会跳过
if (field == null || !field.deserialized) {
in.skipValue();
} else {
// 调用BoundField.read方法,其内部会调用TypeAdapter.read
field.read(in, instance);
}
}
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
in.endObject();
return instance;
}
@Override public void write(JsonWriter out, T value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
out.beginObject();
try {
for (BoundField boundField : boundFields.values()) {
if (boundField.writeField(value)) {
out.name(boundField.name);
boundField.write(out, value);
}
}
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
out.endObject();
}
}
Gson解析中,使用ReflectiveTypeAdapterFactory的解析过程:
5.使用TypeToken需要为什么要使用匿名内部类的方式?
new TypeToken
而在这里使用{},其实就是创建匿名内部类对象,在创建匿名内部类对象,那么其实就可以认为是创建了一个新的类,就是将旧的TypeToken类的中的泛型T都替换成了BaseResponse的新类。这个新类,其实就可以认为是TypeToken中的泛型T都为BaseResponse的一个新类,而不是使用T了。这样,在编译成.class文件的时候,就不会因为泛型擦除而出现T变成Object,而是编译成.class之后,其实就是T都是BaseResponse类型。
匿名内部类对象,其实可以认为是创建了一个新的匿名内部类,然后使用这个匿名内部类来创建了一个对象。
6.Excluder排序器
主要是为了处理一些不需要序列化和不需要反序列化的一些字段的。
(2)返回list集合的fromJson
public TypeAdapter getAdapter(TypeToken type) {
// type的值是java.util.list<类路径>
TypeAdapter> cached = typeTokenCache.get(type);
if (cached != null) {
return (TypeAdapter) cached;
}
Map, FutureTypeAdapter>> threadCalls = calls.get();
boolean requiresThreadLocalCleanup = false;
if (threadCalls == null) {
threadCalls = new HashMap, FutureTypeAdapter>>();
calls.set(threadCalls);
requiresThreadLocalCleanup = true;
}
// the key and value type parameters always agree
FutureTypeAdapter ongoingCall = (FutureTypeAdapter) threadCalls.get(type);
if (ongoingCall != null) {
return ongoingCall;
}
try {
FutureTypeAdapter call = new FutureTypeAdapter();
threadCalls.put(type, call);
for (TypeAdapterFactory factory : factories) {
TypeAdapter candidate = factory.create(this, type);
if (candidate != null) {
call.setDelegate(candidate);
typeTokenCache.put(type, candidate);
return candidate;
}
}
throw new IllegalArgumentException("GSON cannot handle " + type);
} finally {
threadCalls.remove(type);
if (requiresThreadLocalCleanup) {
calls.remove();
}
}
}
而返回List集合,是通过CollectionTypeAdapterFactory这个类里面的内部类来实现的:
private static final class Adapter extends TypeAdapter> {
private final TypeAdapter elementTypeAdapter;
private final ObjectConstructor extends Collection> constructor;
public Adapter(Gson context, Type elementType,
TypeAdapter elementTypeAdapter,
ObjectConstructor extends Collection> constructor) {
this.elementTypeAdapter = new TypeAdapterRuntimeTypeWrapper(context, elementTypeAdapter, elementType);
this.constructor = constructor;
}
@Override public Collection read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
Collection collection = constructor.construct();
in.beginArray();
while (in.hasNext()) {
E instance = elementTypeAdapter.read(in);
collection.add(instance);
}
in.endArray();
return collection;
}
@Override public void write(JsonWriter out, Collection collection) throws IOException {
if (collection == null) {
out.nullValue();
return;
}
out.beginArray();
for (E element : collection) {
elementTypeAdapter.write(out, element);
}
out.endArray();
}
}
在内部类的Adapter中都会有一个read方法,而read方法中,会在内部调用elementTypeAdapter这个类的read方法,而这个类的read方法,其实是调用的TypeAdapterRuntimeTypeWrapper的read方法,而TypeAdapterRuntimeTypeWrapper的read方法是调用了ReflectiveTypeAdapterFactory的内部类Adapter的read方法,也就是通过反射拿到一个个的对象。说明List的形式其实就是通过反射拿到一个Connection对象,再通过反射拿到一个个的对象,然后将这些对象放到Connection中。Map的方式其实是类似的。
(3)返回Map集合
返回Map集合中,Gson.java类中的getAdapter方法中的TypeAdapter
如果key是一个String、int、boolean这样的类型的,则KeyTypeAdapter对象其实就是从TypeAdapters中的对应的TypeAdapter的实现类。而value如果是Object,那么则是通过ReflectiveTypeAdapterFactory的静态final内部类Adapter返回对应的Object的,其实就是通过反射的方式返回的。
JsonReader解析:
(1)beginObject()
int peeked = PEEKED_NONE;
public void beginObject() throws IOException {
int p = peeked;
if (p == PEEKED_NONE) {
p = doPeek();
}
if (p == PEEKED_BEGIN_OBJECT) {
push(JsonScope.EMPTY_OBJECT);
peeked = PEEKED_NONE;
} else {
throw new IllegalStateException("Expected BEGIN_OBJECT but was " + peek() + locationString());
}
}
peeked是个很重要的变量,默认值为PEEKED_NONE。在上面的方法中,调用了一个方法doPeek(),这个类可以说是JsonReader类的核心方法之一。