Java Gson 源码分析:TypeAdapter


#Java Gson


简介

TypeAdapter ,类型适配器,用于将特定的类型与 JSON 字符串之间相互转化。

全路径:com.google.gson.TypeAdapter ,是一个抽象类。实现类有:

  • com.google.gson.internal.bind.CollectionTypeAdapterFactory.Adapter
  • com.google.gson.internal.bind.MapTypeAdapterFactory.Adapter
  • com.google.gson.internal.bind.TypeAdapters.EnumTypeAdapter#EnumTypeAdapter
  • 匿名类,例如 com.google.gson.internal.bind.TypeAdapters#JSON_ELEMENT
  • 等等

不同的 TypeAdapter 的实现都会对应一个工厂类。例如:

  • com.google.gson.internal.bind.CollectionTypeAdapterFactory
  • com.google.gson.internal.bind.MapTypeAdapterFactory
  • 等等

Gson 如何寻找匹配的 TypeAdapter

TypeAdapter 是 TypeAdapterfactory 生成的,TypeAdapterfactory 是一个接口,定义如下:

public interface TypeAdapterFactory {

  <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type);

}

而 Gson 内部会将所有的 TypeAdapterFactory 实现硬编码添加到 factories List 中。通过遍历 list,调用 TypeAdapterFactory#create 方法,若返回不是 null,则认为找到了对应的 TypeAdapter 。具体见源码 com.google.gson.Gson#getAdapter(com.google.gson.reflect.TypeToken<T>)

TypeAdapterFactory#create 是通过类型是否匹配来判断是返回 TypeAdapter 对象,还是返回 null。源码示例:

  private static TypeAdapterFactory newFactory(ToNumberStrategy toNumberStrategy) {
    final NumberTypeAdapter adapter = new NumberTypeAdapter(toNumberStrategy);
    return new TypeAdapterFactory() {
      @SuppressWarnings("unchecked")
      @Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        return type.getRawType() == Number.class ? (TypeAdapter<T>) adapter : null;
      }
    };
  }

TypeAdapter 实现示例

示例: 序列化 int

代码:

package org.example;

import com.google.gson.Gson;
import org.junit.jupiter.api.Test;

public class TestGson {

    @Test
    public void test() {
        Gson gson = new Gson();
        String jsonStr = gson.toJson(123);
        System.out.println(jsonStr);
        // 以上代码输出: 123
    }
}

gson 选择的 TypeAdapter 对象是 com.google.gson.internal.bind.TypeAdapters#INTEGER ,源代码:

  public static final TypeAdapter<Number> INTEGER = new TypeAdapter<Number>() {

    // 序列化为对象
    @Override
    public Number read(JsonReader in) throws IOException {
      if (in.peek() == JsonToken.NULL) {
        in.nextNull();
        return null;
      }
      try {
        return in.nextInt();
      } catch (NumberFormatException e) {
        throw new JsonSyntaxException(e);
      }
    }

    // 反序列化
    @Override
    public void write(JsonWriter out, Number value) throws IOException {
      out.value(value);
    }
  };

示例: 序列化自定义类

package org.example;

import com.google.gson.Gson;
import lombok.Data;
import org.junit.jupiter.api.Test;

public class TestGson {

    @Data
    public static class UserInfo {
        private String name;
    }

    @Test
    public void test() {
        Gson gson = new Gson();
        UserInfo userInfo = new UserInfo();
        userInfo.setName("李白");
        String jsonStr = gson.toJson(userInfo);
        System.out.println(jsonStr);
        // 以上代码输出: {"name":"李白"}
    }
}

gson 对象内部, 使用 com.google.gson.internal.bind.ReflectiveTypeAdapterFactory#create 方法创建 UserInfo 的 TypeAdapter, 最终生成的 TypeAdapter 对象是 com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.Adapter 的实例.


( 本文完 )