Gson源碼分析(二)

Gson解析后的數(shù)據(jù)一般不會(huì)是String類型,而是Object(的子類)或者Array(廣義)類型。先從Object類型說(shuō)起。
假設(shè)需要解析的數(shù)據(jù)如下

{
"name":"張三",
"others":{"phone":"13888888888",
"address":"北京"}
}

其對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)為:

public class TestModel {
    String name;
    Others others;

    public static class Others {
        String phone;
        String address;
    }
}

采用Gson的fromJson方法解析如上數(shù)據(jù),程序會(huì)走到Gson類的getAdapter()方法中

for (TypeAdapterFactory factory : factories) {
        TypeAdapter<T> candidate = factory.create(this, type);
        if (candidate != null) {
          call.setDelegate(candidate);
          typeTokenCache.put(type, candidate);
          return candidate;
        }
      }

通過(guò)判斷create()方法的返回是否為空,來(lái)獲取TypeAdapter。查詢factories中的所有Factory,可能符合如上解析條件的Factory有兩個(gè)。

factories.add(ObjectTypeAdapter.FACTORY);
factories.add(new ReflectiveTypeAdapterFactory(
constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory));

先看第一個(gè)Factory的create()方法。

@Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
      if (type.getRawType() == Object.class) {
        return (TypeAdapter<T>) new ObjectTypeAdapter(gson);
      }
      return null;
    }

如果fromJson()方法傳入的類的Type是Object.class,就采用ObjectTypeAdapter。很顯然,一般情況下不會(huì)是Object,而是Object的子類。
ReflectiveTypeAdapterFactory的create()方法如下:

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

Class的isAssignableFrom()方法用于判斷當(dāng)前Class與傳入的參數(shù)的關(guān)系是否是相等、子類或者接口。如:

Class1.isAssignableFrom(Class2)   

如果Class2跟Class1相等或者Class1是Class2的父類或者Class1是Class2接口,那就就返回true。
再回到ReflectiveTypeAdapterFactory的create()方法。由于java中所有的類都默認(rèn)繼承自O(shè)bject(Java 的偽單繼承),所以,只要是自定義的類,這里都會(huì)返回true。所以所有自定義的Model都會(huì)用ReflectiveTypeAdapterFactory生成的TypeAdapter來(lái)解析。
在create()方法中,有兩個(gè)地方需要注意:
1 constructorConstructor.get(type);
2 getBoundFields(gson, type, raw);
先來(lái)看constructorConstructor.get(type)。

public <T> ObjectConstructor<T> get(TypeToken<T> typeToken) {
    final Type type = typeToken.getType();
    final Class<? super T> rawType = typeToken.getRawType();

    // first try an instance creator

    @SuppressWarnings("unchecked") // types must agree
    final InstanceCreator<T> typeCreator = (InstanceCreator<T>) instanceCreators.get(type);
    if (typeCreator != null) {//instanceCreators初始化的時(shí)候?yàn)榭?,所以這里為空
      return new ObjectConstructor<T>() {
        @Override public T construct() {
          return typeCreator.createInstance(type);
        }
      };
    }

    // Next try raw type match for instance creators
    @SuppressWarnings("unchecked") // types must agree
    final InstanceCreator<T> rawTypeCreator =
        (InstanceCreator<T>) instanceCreators.get(rawType);
    if (rawTypeCreator != null) {
      return new ObjectConstructor<T>() {
        @Override public T construct() {
          return rawTypeCreator.createInstance(type);
        }
      };
    }

    //一般這里會(huì)返回
    ObjectConstructor<T> defaultConstructor = newDefaultConstructor(rawType);
    if (defaultConstructor != null) {
      return defaultConstructor;
    }

    ObjectConstructor<T> defaultImplementation = newDefaultImplementationConstructor(type, rawType);
    if (defaultImplementation != null) {
      return defaultImplementation;
    }

    // finally try unsafe
    return newUnsafeAllocator(type, rawType);
  }


private <T> ObjectConstructor<T> newDefaultConstructor(Class<? super T> rawType) {
    try {
      final Constructor<? super T> constructor = rawType.getDeclaredConstructor();//返回一個(gè)無(wú)參構(gòu)造方法
      if (!constructor.isAccessible()) {
        constructor.setAccessible(true);
      }
      return new ObjectConstructor<T>() {
        @SuppressWarnings("unchecked") // T is the same raw type as is requested
        @Override public T construct() {
          try {
            Object[] args = null;
            return (T) constructor.newInstance(args);//生成一個(gè)實(shí)例,這個(gè)實(shí)例就是fromJson()的返回?cái)?shù)據(jù)
          } catch (InstantiationException e) {
            // TODO: JsonParseException ?
            throw new RuntimeException("Failed to invoke " + constructor + " with no args", e);
          } catch (InvocationTargetException e) {
            // TODO: don't wrap if cause is unchecked!
            // TODO: JsonParseException ?
            throw new RuntimeException("Failed to invoke " + constructor + " with no args",
                e.getTargetException());
          } catch (IllegalAccessException e) {
            throw new AssertionError(e);
          }
        }
      };
    } catch (NoSuchMethodException e) {
      return null;
    }
  }

接下來(lái)看getBoundFields()這個(gè)方法。

private Map<String, BoundField> getBoundFields(Gson context, TypeToken<?> type, Class<?> raw) {
    Map<String, BoundField> result = new LinkedHashMap<String, BoundField>();
    if (raw.isInterface()) {//如果是接口,直接返回
      return result;
    }

    Type declaredType = type.getType();
    while (raw != Object.class) {
      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());//獲取Field的Type
        List<String> fieldNames = getFieldNames(field);//獲取Field的名字,包括注解中的名字
        BoundField previous = null;
        //如果沒(méi)有添加注解名字,fieldNames的size為1
        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 = createBoundField(context, field, name,
              TypeToken.get(fieldType), serialize, deserialize);//創(chuàng)建BoundField
          BoundField replaced = result.put(name, boundField);
          if (previous == null) previous = replaced;
        }
        if (previous != null) {
          throw new IllegalArgumentException(declaredType
              + " declares multiple JSON fields named " + previous.name);
        }
      }
      type = TypeToken.get($Gson$Types.resolve(type.getType(), raw, raw.getGenericSuperclass()));//獲取超類的Type
      raw = type.getRawType();
    }
    return result;
  }

getBoundFields()方法返回的主要就是當(dāng)前類的屬性和屬性類型。這些數(shù)據(jù)就是用于后續(xù)Json數(shù)據(jù)解析的。
createBoundField()這個(gè)方法也很重要。

private 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...
    //Field可以自定義解析,實(shí)現(xiàn)特殊需求
    JsonAdapter annotation = field.getAnnotation(JsonAdapter.class);
    TypeAdapter<?> mapped = null;
    if (annotation != null) {//如果自定義了解析,則采用自定義的解析方法
      mapped = jsonAdapterFactory.getTypeAdapter(
          constructorConstructor, context, fieldType, annotation);
    }
    final boolean jsonAdapterPresent = mapped != null;
    if (mapped == null) mapped = context.getAdapter(fieldType);//獲取Gson的TypeAdapter

    final TypeAdapter<?> typeAdapter = mapped;
    //返回了BoundField,注意其write和read方法
    return new 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);
      }
      @Override void read(JsonReader reader, Object value)
          throws IOException, IllegalAccessException {
        Object fieldValue = typeAdapter.read(reader);//讀取field的值
        if (fieldValue != null || !isPrimitive) {
          field.set(value, fieldValue);//將值寫入到field
        }
      }
      @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
      }
    };
  }

最后看一下ReflectiveTypeAdapterFactory的create()方法返回的TypeAdapter的read()方法。

    @Override public T read(JsonReader in) throws IOException {
      if (in.peek() == JsonToken.NULL) {
        in.nextNull();
        return null;
      }

      T instance = constructor.construct();//獲取實(shí)例

      try {
        in.beginObject();//讀取json數(shù)據(jù)
        while (in.hasNext()) {
          String name = in.nextName();
          BoundField field = boundFields.get(name);
          if (field == null || !field.deserialized) {
            in.skipValue();
          } else {
            field.read(in, instance);//寫入Field對(duì)應(yīng)的數(shù)據(jù)
          }
        }
      } catch (IllegalStateException e) {
        throw new JsonSyntaxException(e);
      } catch (IllegalAccessException e) {
        throw new AssertionError(e);
      }
      in.endObject();
      return instance;//返回結(jié)果
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 基于非墨上一篇關(guān)于泛型的文章,不知道大家是否已經(jīng)做好了閱讀Gson源碼的準(zhǔn)備?本篇文章,非墨將簡(jiǎn)單帶大家過(guò)一下Gs...
    非墨Zero閱讀 4,988評(píng)論 6 14
  • 1.概述2.Gson的目標(biāo)3.Gson的性能和擴(kuò)展性4.Gson的使用者5.如何使用Gson 通過(guò)Maven來(lái)使用...
    人失格閱讀 14,547評(píng)論 2 18
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,525評(píng)論 19 139
  • 生命好短 珍惜多少時(shí)間 何須做繁雜的事情 不必看層出不窮的信息 讓自己的大腦保持清醒 什么段子八卦 什么笑話緋聞 ...
    小品味閱讀 241評(píng)論 4 3
  • 沐若朝閱讀 204評(píng)論 2 1

友情鏈接更多精彩內(nèi)容