在 几篇关于Gson的文章中我们知道Gson解析成Java对象的实现原理是: 1)注册自定义的或者Gson自己定义的TypeAdapter 2)将TypeAdapter封装成TypeAdapterFactory,并把此Factory添加到Gson的factories(List)中 3)通过fromJson方法最终调用getAdapter,遍历factories,获取fromJson的第二个参数type与之对应的TypeAdapterFactory,调用该Factory的create方法来创建一个TypeAdapter 4)调用TypeAdapter的read方法完成json到Java Object的转换。 在我们使用Gson的时候对下面两行代码都不陌生:
Gson gson = new Gson();
Object obj = gson.fromJson(String,Object.class);
这两行代码中你看不到上面所说的任何一个步骤,那么Gson到底是怎么工作的呢?其实简单的追踪一下Gson(),其调用的是Gson的有参构造器,而在这个有参构造器里面就让Gson的factories变量添加了大量的自定义的TypeAdapterFactory,这些TypeAdapterFactory和与之对应的TypeAdapter基本上都在TypeAdapters类里面,当然也有其余的几个单独的TypeAdapter(详见博主写的前几篇关于Gson的博客)!
在正式进入博客主题之前提出一些小问题:在没有自定义自己的TypeAdapter的时候,Gson到底是怎么工作的呢?具体来说调用的是哪个TypeAdapterFactory?而这个TypeAdapterFactory又是create哪个TypeAdapter来完成json的read操作呢?
在回答上面的问题的时候,先说一个事实: 对于每一个Java的基本类型或者集合类型等,Gson都提供了与之相对应的TypeAdapter类型,比如String 类型就有下面的一个TypeAdper:
//与之对应的TypeAdapterFactory
public static final TypeAdapterFactory CHARACTER_FACTORY = newFactory(char.class, Character.class, CHARACTER);
//StringTypeAdapter
public static final TypeAdapter STRING = new TypeAdapter() {
@Override
public String toString() {
return "STRING TypeAdapter";
}
@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);
}
};
基于上面的事实在追踪Gson提供的方法getAdapter方法就可以发现,Gson用反射机制解析Json的流程如下: 前提:通过调用Gson的getAdpter来过滤掉一些不用的TypeAdapterFactory,将能用的到的TypeAdapterFactory放入缓存中,详见getAdapter的一个段代码:
FutureTypeAdapter call = new FutureTypeAdapter();
for (TypeAdapterFactory factory : factories) {
//根据type来从gson的factro获取typeAdapter
TypeAdapter candidate = factory.create(this, type);
//在解析过程中真正需要的TypeAdapter放入typeTokenCache
//这个map对象中进行缓存
if (candidate != null) {
call.setDelegate(candidate);
typeTokenCache.put(type, candidate);
return candidate;
}
}
1)从factories中取ReflectiveTypeAdapterFactory对象 2)调用ReflectiveTypeAdapterFactory的create方法,返回一个Adapter对象
public TypeAdapter create(Gson gson, final TypeToken type) {
Class type, Class raw) {
Map result = new LinkedHashMap();
if (raw.isInterface()) {//如果是接口
return result;
}
//获取类型的全限定名
Type declaredType = type.getType();
while (raw != Object.class) {
//获取你的Java类定义的变量
Field[] fields = raw.getDeclaredFields();
for (Field field : fields) {//遍歷變量的名字
//省略部分代码
field.setAccessible(true);
Type fieldType = $Gson$Types.resolve(type.getType(), raw, field.getGenericType());
//整整构建BoundField的地方,见步骤5
BoundField boundField = createBoundField(context, field, getFieldName(field),
TypeToken.get(fieldType), serialize, deserialize);
BoundField previous = result.put(boundField.name, boundField);
}
type = TypeToken.get($Gson$Types.resolve(type.getType(), raw, raw.getGenericSuperclass()));
raw = type.getRawType();
}
return result;
}
5)以上四个步骤基本上就说明了json反射中的全部流程,在步骤3的while循环中,调用了BoundField的read方法,进行读取;其实BoundFied是一个抽象类,提供了read和write方法,其具体创建的方法是createBoundField方法:
//参数name为json中某一name/value对的name的值
private ReflectiveTypeAdapterFactory.BoundField createBoundField( final Gson context, final Field field, final String name,final TypeToken fieldType, boolean serialize, boolean deserialize) {
//返回构建的BoundField对象
return new ReflectiveTypeAdapterFactory.BoundField(name, serialize, deserialize) {
//此处最为关键,获取当前name对应的fiedType类型的TypeAdpater
//获取对应变量类型的TypeAdpter,这个是关键中的关键
//其中这些TypeAdapter是由Gson自己定义的
final TypeAdapter typeAdapter = context.getAdapter(fieldType);
@SuppressWarnings({"unchecked", "rawtypes"}) // the type adapter and field type always agree
//本篇只讲read,所以此处省略了write方法
@Override void read(JsonReader reader, Object value)
throws IOException, IllegalAccessException {
//实际上的read仍然是typeAdapter对象的read来处理
Object fieldValue = typeAdapter.read(reader);
if (fieldValue != null || !isPrimitive) {
field.set(value, fieldValue);
}
}
};
}
注意观察上面的代码:有这么一个核心的代码:
//获取当前json串的一个name/value的name对应JavaBean里面的变量类型type,或者这个type对应的TypeAdpater类
final TypeAdapter
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?