Gson源码深入分析(一)

供销合作社项目中选择Gson框架对服务器传过来的Json数据进行剖释,而服务器后台数据相当的大程度上是透过运行后台人士配置。由于各个缘由运转恐怕将某一字段类型配置错误,比方会集类型配置成字符串类型。固然事业层会实行丰裕的抓获,不过仅因为贰个字段的错误,导致整个Json数据失效,因小失大,乃至或许会招致重大损失,比如直播间礼物墙,因为贰个礼物的某一个字段的一无所长,导致整个礼物墙呈现为空,在线上景况这一个好不轻易重大事故了。于是,一个对中央类型容错的Gson改动库的须要出现,对于错误的数据以暗许值填充。

干货地址:类型容错的Gson

Github地址

a. 当前解析的Gson版本号为2.8.1。b.
Gson的管理进度重要分为多个流向,三个是种类化,将javabean对象转化为json字符串;另一个是反种类化,将json字符串映射成javabean对象。c.
那七个流向管理前都有二个二头的操作,从传出的java实例对象大概字节码对象中拿走
TypeAdapter,对于种类化就通过Jsonwriter进行写,对于反体系化就经过JsonReader举办读,所以此篇只深入分析Gson读的进程,写管理操作流程同样。

Json剖析平昔是网络通讯中要害的数目分析框架。而Gson和法斯特Json是极度常用的三个Json深入分析框架。这一章节器重介绍Gson的法规。Gson的贰个天下无双使用例子如下:

Gson简介

json因其轻量、高效等特点,而被大范围用作移动支付的新闻相互的载体。
大家精晓AndroidSDK提供了org.json工具包来分析Json数据,不过照旧幸免不理解析进程中的一两种重复工作。所以就应时而生了众多第三方JSON深入分析框架。JSON官网也给我们列出了在各个语言中JSON的分析攻略:

365bet亚洲真人 1

JSON解析库

能够看出java语言中深入分析JSON的库有过多,但由于活动器具硬件与软件等各方面包车型地铁成分,在那一个库中相比较符合用于移动支付的要紧有Gson和法斯特Json。
前几日我们先来介绍以下Gson。

Gson是Google自家开垦的,所以谷歌(Google)也极力推荐使用这些库来解析JSON数据。
Google自个儿是这么说的:已经有点开源项目可用来将Java对象调换到JSON,然则那在那之中山大学部分内需您在Bean类中加多Java注明,非常多时候须求您自个儿去写Bean对象,何况大非常多也不援救Java泛型。所以谷歌(Google)开垦Gson有以下多少个开荒目的:
1.提供超轻便的toJson()和fromJson()方法来贯彻Java对象与JSON对象的相互调换。
2.允许不可变对象与JSON之间进行相互转变。
3.支持Java泛型
4.支撑别的复杂的靶子(深层包括与泛型)

http://www.jianshu.com/p/89c314ae8c0b

  • Gson 开采者间接利用的类,只对输入和输出肩负。
  • TypeToken
    封装“操作类”(Gson.fromJson(json,People.class、Gson.toJson(new
    People)) 两处的People都以操作类)的品类。
  • TypeAdapter
    间接操作类别化与反连串化的进度,所以该抽象类中存在read()和write方法。
  • TypeAdapterFactory 用于生产TypeAdapter的厂子类。
  • GsonReader和GsonWriter是Gson管理内容的包装流,主旨的操作有:
    • peek() 流中下几个亟待管理的开始和结果
    • nextName() 读取json的key
    • nextString() 读取贰个String类型的value
    • nextInt() 读取一个String类型的value
    • nextBoolean() 读取贰个Boolean类型的value
        String jsonString = "{\"name\":\"renyiguang\"}";
        Gson gson = new Gson();
        TestModel testModel = gson.fromJson(jsonString, TestModel.class);

添加Gradle依赖

compile 'com.google.code.gson:gson:2.8.0'  

介绍

Gson(又称GoogleGson)是谷歌(Google)集团揭露的叁个绽开源代码的Java库,主要用途为连串化Java对象为JSON字符串,或反种类化JSON字符串成Java对象。

5. 源码分析。

从Gson.from(json, People.class) 突入

 fromJson(json,Peolple.class)的调用链 public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException { Object object = fromJson(json,  classOfT); return Primitives.wrap.cast; } public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException { if (json == null) { return null; } StringReader reader = new StringReader; T target =  fromJson(reader, typeOfT); return target; } public <T> T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException { JsonReader jsonReader = newJsonReader; T object =  fromJson(jsonReader, typeOfT); assertFullConsumption(object, jsonReader); return object; } public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException { boolean isEmpty = true; boolean oldLenient = reader.isLenient(); reader.setLenient; try { reader.peek(); isEmpty = false; TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get; TypeAdapter<T> typeAdapter = getAdapter(typeToken); T object = typeAdapter.read; return object; } ... }

下面是从fromJson(String json, Class<T>
classOfT)切入,亦恐怕是从fromJson(JsonElement json, Class<T>
classOfT)也好,最终都以由 fromJson(JsonReader reader, Type
typeOfT)处理。

  • TypeToken对象的收获
  • 根据TypeToken获取TypeAdapter对象
  • 由TypeAdapter对象深入分析json字符串

Gson的fromJson()方法源码如下:

下载地址:

Github:https://github.com/google/gson
MVN:https://mvnrepository.com/artifact/com.google.code.gson/gson

基本概念

  • Serialization:种类化,使Java对象到Json字符串的进度。
  • Deserialization:反连串化,字符串转换来Java对象。
  • JSON数据中的JsonElement有上面这两种档期的顺序:

JsonPrimitive —— 例如一个字符串或整型
JsonObject—— 一个以 JsonElement 名字(类型为 String)作为索引的集合。也就是说可以把 JsonObject 看作值为 JsonElement 的键值对集合。
JsonArray—— JsonElement 的集合。注意数组的元素可以是四种类型中的任意一种,或者混合类型都支持。
JsonNull—— 值为null

咱俩先从轻易的出手,请牢记大家的例子:

gson.fromJson(“hello gson”,String.class)

  public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException {
    Object object = fromJson(json, (Type) classOfT);
    return Primitives.wrap(classOfT).cast(object);
  }

  public <T> 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;
  }

  public <T> T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException {
    JsonReader jsonReader = newJsonReader(json);
    T object = (T) fromJson(jsonReader, typeOfT);
    assertFullConsumption(object, jsonReader);
    return object;
  }

  public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
    boolean isEmpty = true;
    boolean oldLenient = reader.isLenient();
    reader.setLenient(true);
    try {
      reader.peek();
      isEmpty = false;
      TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);//1获取TypeToken
      TypeAdapter<T> typeAdapter = getAdapter(typeToken);//2获取TypeAdapter
      T object = typeAdapter.read(reader);//3解析
      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);
    }
  }

API文档

http://www.javadoc.io/doc/com.google.code.gson/gson/2.8.0

gson消除的难点

  • 提供一种像toString()和构造方法的很简短的机制,来贯彻Java
    对象和Json之间的相互转变。
  • 同意已经存在的力不胜任退换的指标,调换到Json,恐怕Json调换到已存在的对象。
  • 同意自定义对象的表现方式;
  • 支撑放肆的复杂性对象;
  • 可见转移可削减和可读的Json的字符串输出。

1. TypeToken的获取

 public static TypeToken<?> get(Type type) { return new TypeToken<Object>; }

没什么好瞅的~ 看new吧!

 TypeToken(Type type) { this.type = $Gson$Types.canonicalize($Gson$Preconditions.checkNotNull; this.rawType = (Class<? super T>) $Gson$Types.getRawType(this.type); this.hashCode = this.type.hashCode(); }

动用公约式对传播的type判空管理,然后拿走type的(type、rawType和hashcode),分别拜见type和rawtype的收获流程

如上,fromJson()方法重要分多个步骤:1获取TypeToken,2获取TypeAdapter,3使用TypeAdapter分析。
上边就依据这个步骤剖析。
(1)TypeToken
TypeToken的get()方法源码如下:

GSON的使用

gson注解

1. type的得到(type的雍容华贵包装)
public static Type canonicalize(Type type) { if (type instanceof Class) { Class<?> c = (Class<?>) type; return c.isArray() ? new GenericArrayTypeImpl(canonicalize(c.getComponentType : c; } else if (type instanceof ParameterizedType) { ParameterizedType p = (ParameterizedType) type; return new ParameterizedTypeImpl(p.getOwnerType(), p.getRawType(), p.getActualTypeArguments; } else if (type instanceof GenericArrayType) { GenericArrayType g = (GenericArrayType) type; return new GenericArrayTypeImpl(g.getGenericComponentType; } else if (type instanceof WildcardType) { WildcardType w = (WildcardType) type; return new WildcardTypeImpl(w.getUpperBounds(), w.getLowerBounds; } else { // type is either serializable as-is or unsupported return type; }

跻身规范化的筛选,第2个if仍旧好驾驭,后边的是哪些鬼?
不用焦急,待小编给施主梳理,以前Gson.from(json,
People.class)的调用链中有三个fromJson(Reader json, Type
typeOfT),顾客使用时的切入点假诺是它就可能是筛选情状的别的规格,此再次回到的type相对于对传播的java类型举办的档案的次序的再度打包。

  public static TypeToken<?> get(Type type) {
    return new TypeToken<Object>(type);
  }

  TypeToken(Type type) {
    this.type = $Gson$Types.canonicalize($Gson$Preconditions.checkNotNull(type));
    this.rawType = (Class<? super T>) $Gson$Types.getRawType(this.type);
    this.hashCode = this.type.hashCode();
  }

1.创建Gson对象

调用构造方法new Gson(),或然选用GsonBuilder类构造Gson对象

源码深入分析

Gson其实正是一套模型调换工具,他的一端连接的是json数据格式编码流,另一头便是我们的Java对象模型。大家先给自身找三个入口点,看下Gson二个大范围的例证:

public static class ClassRoom {
      public String roomName;
      public int number;

      public String toString() {
         return "[" + roomName + ":" + number + "]";
      }
 }

 public static class User {
      public String name;
      public int age;
      private ClassRoom room;

      @Override
      public String toString() {
       // TODO Auto-generated method stub
       return name + "->" + age + ":" + room;
      }
 }

我们品尝传入三个json格式的多少串

Gson gson = new Gson();
String strJson = "{name:'david',age:19,room:{roomName:'small',number:1}}";
User u = gson.fromJson(strJson, User.class);

在上述代码中,gson约等于起到了一个数量适配器的效应,将叁个Json的数据格式转变为贰个Java业务可用的数据模型。而这一层的转移,是由此Gson的fromJson方法完成的。

public <T> 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;
  }

Gson帮忙以流的方法来读取字符,为了接口的复用性,借使您的第贰个参数输入的是一个String对象,Gson同样会将它包裹成为叁个流对象String里德r。Gson的fromJson会调用到联合的接口方法
T fromJson(Json里德r reader, Type typeOfT) 中去:

//code 2
 public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
        boolean isEmpty = true;
        boolean oldLenient = reader.isLenient();
        reader.setLenient(true);//不严格按照Json标准语法
        try {
            reader.peek();
            isEmpty = false;
            TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);
            TypeAdapter<T> typeAdapter = getAdapter(typeToken);
            T object = typeAdapter.read(reader);
            return object;
        } catch (EOFException e) {
               ............
        }
    }

在code2代码主要做了上边包车型大巴事体:

  1. 大家传入的一个StringReader,将会另行被打包成为三个Json语法格式的JsonReader对象;
  2. 由此调用setLenient方法,给Json语法提供越来越大的宽容度;
  3. 经过reader.peek方法,先做一回语法检查,并获取第三个非空字符,通过那一个非空字符来标志下二个深入分析格式;
  4. 365bet亚洲真人,透过传播的类型Type,来博取那几个类型对应的TypeToken;
  5. 由此转移的TypeToken来扭转对应的适配器;(Gson的意义,是将Json数据模型往分化平台上的Java对象转变,实际上能够算是一种平台接口的转变,这里,Gson用了适配器的办法来达成那套方案)。
    大家来一步步地看下代码,代码一进来,reader就调用了三个peek操作,那是干吗吧?我们领略,在流式对象中,peek的指标是为着查看下贰个字符,JsonReader也自然如此。JsonReader通过一遍peek先做一个简短的语法校验,然后评释当前Json里德r解析的时候将以何种方式深入分析。

//code3
public JsonToken peek() throws IOException {
    int p = peeked;
    if (p == PEEKED_NONE) {
      p = doPeek();
    }
   ....
}

peek方法并不像大家前面包车型客车流式文件那样,再次来到一个实际的数目,而是回到贰个脚下的深入分析状态标记JsonToken。JsonToken是三个枚举类型,用来标记在Json多少格式中的各类语法单位。而在peek()函数的在这之中,又调用了贰个doPeek()。即便多个名字极度一致,然而回到的结果却是完全不一样。doPeek是当真意义上的回到数据,也正是重临八个诚实的字符:

//code doPeek()
 private int doPeek() throws IOException {
      stack[stackSize - 1] = JsonScope.NONEMPTY_DOCUMENT;
       switch (c) {
                case '"':
                    return peeked = PEEKED_DOUBLE_QUOTED_NAME;
                case '\'':
                    checkLenient();
                    return peeked = PEEKED_SINGLE_QUOTED_NAME;
                case '}':
                    if (peekStack != JsonScope.NONEMPTY_OBJECT) {
                        return peeked = PEEKED_END_OBJECT;
                    } else {
                        throw syntaxError("Expected name");
                    }
                default:
      }
  }

在doPeek()函数中,需求选拔二个叫做stack变量的数额,里面存放的是名称为JsonScope的一堆常量。那是因为,Gson对Json的深入分析方法,是行使栈式的深入分析,依据档次深入分析的点子,这种档次剖判的主意索要用栈来记录一些从前的情事。而以此stack的上马值,在一个方始代码块中安装:

 private int[] stack = new int[32];
  public int stackSize = 0;
  {
      stack[stackSize++] = JsonScope.EMPTY_DOCUMENT;
  }

看得出,stack早先栈顶数据为EMPTY_DOCUMENT常量。那时候,大家再次回到doPeek函数中去。大家得以看到:

  1. if将调用line第11中学的方法体。将栈顶数据替换为NONEMPTY_DOCUMENT状态
  2. 在line第22中学拿走下一个非空白字符,赋值给c变量
  3. 在line3元帅执行case ‘{‘将PEEKED_BEGIN_OBJECT
    整型常量付给peeked变量,然后回来。
    接下来我们回来大家的peek()方法:

int p = peeked;
    if (p == PEEKED_NONE) {
      p = doPeek();
    }
    switch (p) {
    case PEEKED_BEGIN_OBJECT:
      return JsonToken.BEGIN_OBJECT;
}

doPeek方法重回二个整型的常量后,peek方法又通过那么些整型常量转化为对应的JsonToken变量。大概有一点点看官就能够问了,假如是这样的话,JsonToken的意义何在呢?你一丝一毫能够用再次来到的peeked变量来代替JsonToken的数目?

case PEEKED_SINGLE_QUOTED_NAME:
    case PEEKED_DOUBLE_QUOTED_NAME:
    case PEEKED_UNQUOTED_NAME:
      return JsonToken.NAME;

咱俩能够见到,三种peek出来的数据类型,实际上或许对应一种Json中的标志符,那么,也便是说peek出来的暗号类型(整型常量)跟Json中的标记符(JsonToken枚举常量),实际上是一种多对应的数目涉嫌,所以不能够混用。其余,大家在peek()方法中所生成的那一个JsonToken,在Reader中并从未记录,也正是说,对于数据的分析,Reader依旧关注doPeek方法中变化的中间状态数据。

大家回来code第22中学,依据上边的剖析,大家早已知道reader.peek()方法其实是发端了有个别数额变量。接下去,fromJson方法将透过TypeToken.get的静态方法来生成叁个TypeToken对象。

public static TypeToken<?> get(Type type) {
        return new TypeToken<Object>(type);
  }

TypeToken的get形式,是一种静态构造工厂,它将平昔回到二个TypeToken对象。

Gson gson = new Gson();
String strJson = "{name:'david',age:19,room:{roomName:'small',number:1}}";
User u = gson.fromJson(strJson, User.class);

当TypeToken.get(User.class)的时候,重返的正是三个里面装有一个User.class为Type的TypeToken变量,在经过TypeToken.get(Type)方法调用现在,将会透过二个叫getAdapter的必定要经过的地方来获得typeAdapter对象。
TypeAdapter是Gson代码种类中的至关重要,它承受了真正意义上的改动专门的学问。
Gson在Adapter的管理上,利用了享元
,终究,分析类结构有鲜明的小时开支,为了降低这种时刻上的付出,Gson使用了缓冲池来保管这种映射关系。大概读者有多少个标题:既然TypeToken.get方法每一回都以利用静态工厂的诀窍组织多少个新的TypeToken,那么你在放入cache中并无法起到cache的机能?
答案是:能够的。回答那一个难题,大家要求再次来到TypeToken的源码:

    @Override
    public final int hashCode() {
        return this.hashCode;
    }

    @Override
    public final boolean equals(Object o) {
        return o instanceof TypeToken<?> && $Gson$Types.equals(type, ((TypeToken<?>) o).type);
    }

如上述代码显示,TypeToken利用同一的hashCode和复写的equals方法,来缓和不一样目的的抵触难点。好的,我们后续回到get艾达pter方法:

// code Gson.getAdapter
public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {
      TypeAdapter<?> cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type);
      if (cached != null) {
          return (TypeAdapter<T>) cached;
      }

      Map<TypeToken<?>, FutureTypeAdapter<?>> threadCalls = calls.get();
      boolean requiresThreadLocalCleanup = false;
      if (threadCalls == null) {
          threadCalls = new HashMap<TypeToken<?>, FutureTypeAdapter<?>>();
          calls.set(threadCalls);
          requiresThreadLocalCleanup = true;
      }

      // the key and value type parameters always agree
      FutureTypeAdapter<T> ongoingCall = (FutureTypeAdapter<T>) threadCalls.get(type);
      if (ongoingCall != null) {
          return ongoingCall;
      }

      try {
          FutureTypeAdapter<T> call = new FutureTypeAdapter<T>();
          threadCalls.put(type, call);

          for (TypeAdapterFactory factory : factories) {
              TypeAdapter<T> 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();
          }
      }
  }

当cache中并子虚乌有须求的适配器的时候,并且该线程并海市蜃楼有缓冲池对象的时候,Gson将组织一个Map对象,归入线程中。同期大家还足以发掘Gson的Cache的特色:

  1. 在Gson的Cache处理里,实际上利用了二级缓冲;
  2. Gson对象内部有三个缓冲,而Gson对象所在的线程又有三个分享Cache;
  3. 在差别的线程之间,又利用差别的cache。

//核心代码
FutureTypeAdapter<T> call = new FutureTypeAdapter<T>();
      threadCalls.put(type, call);
      for (TypeAdapterFactory factory : factories) {
        TypeAdapter<T> candidate = factory.create(this, type);
        if (candidate != null) {
          call.setDelegate(candidate);
          typeTokenCache.put(type, candidate);
          return candidate;
        }
      }

Adapter的结构是经过遍历三个factories会集类来实现的。做法也很简短,Factory通过匹配传入的TypeToken类型,然后是不是合营,假诺协作将扭转对象,分化盟就回到null。同有的时候间,一旦生成Adapter对象,程序及时回到,表达构造对象是有优先级其他,或许您的AFactory通过准则可以转移对象,BFactory通过法则也足以生成对象,那么今年纵然AFactory在BFactory的前头,那么将开始时期选拔AFactory来布局Adapter。
factories的开首化数据在Gson的结构器里:

 Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingStrategy,
         final Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls,
         boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
         boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,
         LongSerializationPolicy longSerializationPolicy,
         List<TypeAdapterFactory> typeAdapterFactories)
{
     factories.add(TypeAdapters.JSON_ELEMENT_FACTORY);//针对JsonElement类做特别处理
        factories.add(ObjectTypeAdapter.FACTORY);//针对Object类做特殊处理

        // the excluder must precede all adapters that handle user-defined types
        factories.add(excluder);//用于拦截一些不在使用的类型

        // user's type adapters
        factories.addAll(typeAdapterFactories);

        // type adapters for basic platform types
        factories.add(TypeAdapters.STRING_FACTORY);
        factories.add(TypeAdapters.INTEGER_FACTORY);
        factories.add(TypeAdapters.BOOLEAN_FACTORY);
        factories.add(TypeAdapters.BYTE_FACTORY);
        factories.add(TypeAdapters.SHORT_FACTORY);
        TypeAdapter<Number> longAdapter = longAdapter(longSerializationPolicy);
        factories.add(TypeAdapters.newFactory(long.class, Long.class, longAdapter));
        factories.add(TypeAdapters.newFactory(double.class, Double.class,
                doubleAdapter(serializeSpecialFloatingPointValues)));
        factories.add(TypeAdapters.newFactory(float.class, Float.class,
                floatAdapter(serializeSpecialFloatingPointValues)));
        factories.add(TypeAdapters.NUMBER_FACTORY);
        factories.add(TypeAdapters.ATOMIC_INTEGER_FACTORY);
        factories.add(TypeAdapters.ATOMIC_BOOLEAN_FACTORY);
        factories.add(TypeAdapters.newFactory(AtomicLong.class, atomicLongAdapter(longAdapter)));
        factories.add(TypeAdapters.newFactory(AtomicLongArray.class, atomicLongArrayAdapter(longAdapter)));
        factories.add(TypeAdapters.ATOMIC_INTEGER_ARRAY_FACTORY);
        factories.add(TypeAdapters.CHARACTER_FACTORY);
        factories.add(TypeAdapters.STRING_BUILDER_FACTORY);
        factories.add(TypeAdapters.STRING_BUFFER_FACTORY);
        factories.add(TypeAdapters.newFactory(BigDecimal.class, TypeAdapters.BIG_DECIMAL));
        factories.add(TypeAdapters.newFactory(BigInteger.class, TypeAdapters.BIG_INTEGER));
        factories.add(TypeAdapters.URL_FACTORY);
        factories.add(TypeAdapters.URI_FACTORY);
        factories.add(TypeAdapters.UUID_FACTORY);
        factories.add(TypeAdapters.CURRENCY_FACTORY);
        factories.add(TypeAdapters.LOCALE_FACTORY);
        factories.add(TypeAdapters.INET_ADDRESS_FACTORY);
        factories.add(TypeAdapters.BIT_SET_FACTORY);
        factories.add(DateTypeAdapter.FACTORY);
        factories.add(TypeAdapters.CALENDAR_FACTORY);
        factories.add(TimeTypeAdapter.FACTORY);
        factories.add(SqlDateTypeAdapter.FACTORY);
        factories.add(TypeAdapters.TIMESTAMP_FACTORY);
        factories.add(ArrayTypeAdapter.FACTORY);
        factories.add(TypeAdapters.CLASS_FACTORY);

        // type adapters for composite and user-defined types
        factories.add(new CollectionTypeAdapterFactory(constructorConstructor));
        factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization));
        this.jsonAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor);
        factories.add(jsonAdapterFactory);
        factories.add(TypeAdapters.ENUM_FACTORY);
        factories.add(new ReflectiveTypeAdapterFactory(
                constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory));

        this.factories = Collections.unmodifiableList(factories);
}

,当大家传入二个User.class类型的时候,Gson会通过ReflectiveTypeAdapterFactory厂子来生产贰个Adapter来适配Json对象:

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));
  }

发表评论

电子邮件地址不会被公开。 必填项已用*标注