通过Gson的反射解析机制详解(1)和Gson的反射解析机制详解(2) 这两篇博文我们知道Gson的通过反射工作的原理其实就是一句话: 根据Type遍历Class的Field属性,然后调用Field.set(obj,value)方法为一个属性赋值,其中obj是一个javabean的对象实例。
本篇就简单讲讲这个obj 在gson中是怎么初始化这个obj的。从中体会汲取Gson 优秀的设计理念。这里涉及到了InstanceCreator接口的使用。
public interface InstanceCreator {
public T createInstance(Type type);
}
该接口的作用也很简单,顾名思义就是对象创建者,就是根据传入的类型返回一个JavaBean对象,比如你可以这么使用(更多例子点击此处或者此处):
public void testInstanceCreatorReturnsBaseType(){
Gson gson=new GsonBuilder().registerTypeAdapter(Base.class,new InstanceCreator(){
public Base createInstance( Type type){
return new Base();
}
}
).create();
String json="{baseName:'BaseRevised',subName:'Sub'}";
Base base=gson.fromJson(json,Base.class);
assertEquals("BaseRevised",base.baseName);
}
该结口的主要作用就是初始化File.setValue(obj,value)的中的这个obj,根据前面对Gson讲解的博文我们知道Gson在初始化对象的时候是由如下代码的(建议看博主的其他关于Gson的解析):
//创建对象的实例:这段至关重要 参考《Gson反射解析机制详解(1)》
public T read(JsonReader in) throws IOException {
//....
//实例化一个对象
T instance = constructor.construct();
in.beginObject();
//遍历json为instance的字段自动赋值
while (in.hasNext()) {
String name = in.nextName();
BoundField field = boundFields.get(name);
if (field == null || !field.deserialized) {
in.skipValue();
} else {
field.read(in, instance);
}
}
in.endObject();
//返回一个java bean对象
return instance;
}
上述reader的方法的主要目的就是调用gson.fromJson(json,Base.class)的时候返回给你一个Base对象,该对象就是通过:
T instance = constructor.construct();
来初始化的。
都到此处你可能会问,不是说javaBean的初始化是通过InstanceCreator接口的createInstance方法初始化的么?这个constructor.construct()是什么鬼? 带着着两个问题,先来看看InstanceCreator是怎么注入到Gson中的。
纵观一些常用的框架,构建着模式起到了很大的作用,常用的库都使用了构建者模式:EventBus,ImageLoader,Glide,Fresco,Okhttp等等等,Gson也不例外----GsonBuilder. 配置InstanceCreator的时候就是在GsonBuilder来配置的(见文章开头的例子)。在GsonBuilder中提供了registerTypeAdapter方法来注册用户自己的InstanceCreator:
private final Map>();
public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter) {
if (typeAdapter instanceof InstanceCreator) {
//放入map中
instanceCreators.put(type, (InstanceCreator) typeAdapter);
}
//省略部分代码
return this;
}
上面代码也很简单就是将type及其对应的InstanceCreator放入一个map中。在构建Gson对象的时候将此map传给了gson对象,详见GsonBuilder的create方法:
public Gson create() {
addTypeAdaptersForDate(datePattern, dateStyle, timeStyle, factories);
//删除与本文无关的代码
return new Gson(...,..., instanceCreators,
..., ...,
..., ..., ..., ...,
..., ..., ...);
}
然后进入对应的Gson构造方法:
private final ConstructorConstructor constructorConstructor;
Gson(。。。,
final Map> instanceCreators) {
this.instanceCreators = instanceCreators;
}
}
所以我们在通过ReflectiveTypeAdapterFactory对象初始化TypeAdapter的时候就有了如下这一段:
public TypeAdapter create(Gson gson, final TypeToken type) {
//根据type获取ObjectConstructor
ObjectConstructor constructor = constructorConstructor.get(type);
return new Adapter(constructor, getBoundFields(gson, type, raw));
}
需要知道的是ObjectConstructor也是一个接口,其目的是初始化目标javaBean对象:
public interface ObjectConstructor {
/**
* Returns a new instance.
*/
public T construct();
}
那么问题又来了,上面说过InstanceCreator是用来初始化javaBean对象,怎么又冒出来一个ObjectConstructor呢?其实很简单,在ConstructorConstructor的get方法中可以方法下么一段:
//返回一个ObjectConstructor对象。
public ObjectConstructor get(TypeToken typeToken) {
final Type type = typeToken.getType();
final Class
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【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脚手架写一个简单的页面?