美文网首页
Gson 源码一步一步的分析和总结

Gson 源码一步一步的分析和总结

作者: 666swb | 来源:发表于2017-12-26 18:02 被阅读28次

    一:序列化

    常用对象转化为字符串
    String result = new Gson().toJson(object);

    定位Gson类的构造方法

    其中有重要的 List<TypeAdapterFactory> factories, 以及其他变量
     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) {
        this.constructorConstructor = new ConstructorConstructor(instanceCreators);
        this.excluder = excluder;
        this.fieldNamingStrategy = fieldNamingStrategy;
        this.serializeNulls = serializeNulls;
        this.generateNonExecutableJson = generateNonExecutableGson;
        this.htmlSafe = htmlSafe;
        this.prettyPrinting = prettyPrinting;
        this.lenient = lenient;
    
        List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
    
        // built-in type adapters that cannot be overridden
        factories.add(TypeAdapters.JSON_ELEMENT_FACTORY);
        factories.add(ObjectTypeAdapter.FACTORY);
    
        // 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);
      }
    

    最关键方法

    /**
       * Writes the JSON representation of {@code src} of type {@code typeOfSrc} to
       * {@code writer}.
       * @throws JsonIOException if there was a problem writing to the writer
       */
      @SuppressWarnings("unchecked")
      public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOException {
        TypeAdapter<?> adapter = getAdapter(TypeToken.get(typeOfSrc));
        boolean oldLenient = writer.isLenient();
        writer.setLenient(true);
        boolean oldHtmlSafe = writer.isHtmlSafe();
        writer.setHtmlSafe(htmlSafe);
        boolean oldSerializeNulls = writer.getSerializeNulls();
        writer.setSerializeNulls(serializeNulls);
        try {
          ((TypeAdapter<Object>) adapter).write(writer, src);
        } catch (IOException e) {
          throw new JsonIOException(e);
        } finally {
          writer.setLenient(oldLenient);
          writer.setHtmlSafe(oldHtmlSafe);
          writer.setSerializeNulls(oldSerializeNulls);
        }
      }
    

    方法中的第一行

    TypeAdapter<?> adapter = getAdapter(TypeToken.get(typeOfSrc));

    其中TypeToken类

    TypeToken是支持泛型,通过反射获取Type和Class(由于JVM中泛型的类型插除,所以来发射获取Type)
    TypeToken主要是用于提供Type,获得相应的TypeAdapter

    图片.png

    方法 getSuperclassTypeParameter(getClass());

     /**
       * Returns the type from super class's type parameter in {@link $Gson$Types#canonicalize
       * canonical form}.
       */
      static Type getSuperclassTypeParameter(Class<?> subclass) {
        //获取父类泛型类型Type
        Type superclass = subclass.getGenericSuperclass();
        //Class的类型抛出异常
        if (superclass instanceof Class) {
          throw new RuntimeException("Missing type parameter.");
        }
        //父类转换是泛型Type
        ParameterizedType parameterized = (ParameterizedType) superclass;
       //Type数组第一个泛型T的数据
        return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
      }
    

    上面的这个方法,经常在网络返回解析字符串为对象bean集合时使用

    List<City> cityList = new Gosn().fromJson(string, new TypeToken<List<City>>(){}.getType());
    或者
    T obj = new Gson().fromJson(string, (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]);

    其中TypeAdapter类的getAdapter方法
    /**
       * Returns the type adapter for {@code} type.
       *
       * @throws IllegalArgumentException if this GSON cannot serialize and
       *     deserialize {@code type}.
       */
      @SuppressWarnings("unchecked")
      public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {
        //typeTokenCache是Map<TypeToken<?>, TypeAdapter<?>> 对应的TypeToken,
        //然后获取到TypeAdapter,Gson初始化时的factories总初始化了很多的TypeAdapter,例如:ObjectTypeAdapter
        TypeAdapter<?> cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type);
        if (cached != null) {
          return (TypeAdapter<T>) cached;
        }
    
       //代理FutureTypeAdapter,
        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);
    
          //Gson初始化的factories
          for (TypeAdapterFactory factory : factories) {
            TypeAdapter<T> candidate = factory.create(this, type);
            if (candidate != null) {
              call.setDelegate(candidate);
              //cashe对应的Map<TypeToken<?>, TypeAdapter<?>>
              typeTokenCache.put(type, candidate);
              return candidate;
            }
          }
          throw new IllegalArgumentException("GSON cannot handle " + type);
        } finally {
          threadCalls.remove(type);
    
          if (requiresThreadLocalCleanup) {
            calls.remove();
          }
        }
      }
    

    不同对象对应的TypeAdapter,打断点看看吧

    当new Gson().tosjson(1); 对应TypeAdapters

    图片.png
    当new Gson().tojson(new BaseBean());对应ReflectiveTypeAdapterFactory
    图片.png

    将对象转换字符串的写操作((TypeAdapter<Object>) adapter).write(writer, src);

    这里就是TypeAadpter的write方法了, 以ObjectTypeAdapter为列子,看它的write方法

    @SuppressWarnings("unchecked")
      @Override public void write(JsonWriter out, Object value) throws IOException {
        if (value == null) {
          out.nullValue();
          return;
        }
    
        TypeAdapter<Object> typeAdapter = (TypeAdapter<Object>) gson.getAdapter(value.getClass());
        if (typeAdapter instanceof ObjectTypeAdapter) {
         //这个开始
          out.beginObject();
          out.endObject();
          return;
        }
        //写
        typeAdapter.write(out, value);
      }
    
    beginObject()
    public JsonWriter beginObject() throws IOException {
        writeDeferredName();
        return open(EMPTY_OBJECT, "{");
      }
    
    open()
    private JsonWriter open(int empty, String openBracket) throws IOException {
        beforeValue();
        push(empty);
        out.write(openBracket);
        return this;
      }
    
    其中的typeAdapter.write的写字符流来操作数据,最后得到字符串
    typeAdapter.write(out, value);
    

    反序列化的原理一样的,就不说了

    原理小结:Gson支持泛型,通过反射获取对象的Type, 然后根据Type获取到对应的TypeAdapter, 最后通过字符流的方式进行写和读操作,内部部的Json与Java间的转换依赖于各类的TypeAdapter等。

    参考:
    http://blog.csdn.net/maplejaw_/article/details/51818570
    https://www.jianshu.com/p/8cc857583ff4
    http://blog.csdn.net/u012422440/article/details/48860893
    http://blog.csdn.net/u013480667/article/details/51771467
    Gson:自定义TypeAdapter

    相关文章

      网友评论

          本文标题:Gson 源码一步一步的分析和总结

          本文链接:https://www.haomeiwen.com/subject/pdpdgxtx.html