您当前的位置: 首页 > 

郭梧悠

暂无认证

  • 1浏览

    0关注

    402博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Gson源码解析之InstanceCreator简单说明

郭梧悠 发布时间:2018-08-01 16:27:38 ,浏览量:1

通过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            
关注
打赏
1663674776
查看更多评论
0.0370s