共计 5697 个字符,预计需要花费 15 分钟才能阅读完成。
1: 到官网看下 gson 的次要作用就是 Java Objects 和 JSON 之间的互相转换. 咱们看个最简略的例子.
@AllArgsConstructor | |
public static class Book{ | |
private Integer id; | |
private String name; | |
} | |
public static void main(String[] args) {Map<String,Book> map = Maps.newHashMap(); | |
map.put("1", new Book(1,"1")); | |
map.put("2", new Book(2,"2")); | |
map.put("3", new Book(3,"3")); | |
final Gson gson = new Gson(); | |
final String json = gson.toJson(map); | |
System.out.println(json); | |
final Map map1 = gson.fromJson(json, new TypeToken<Map<String,Book>>(){}.getType()); | |
System.out.println(map1); | |
} | |
#输入后果 | |
{"1":{"id":1,"name":"1"},"2":{"id":2,"name":"2"},"3":{"id":3,"name":"3"}} | |
{1=com.company.gson.Main$Book@491cc5c9, 2=com.company.gson.Main$Book@74ad1f1f, 3=com.company.gson.Main$Book@6a1aab78} |
可见 Java Object 转成了 json 字符串,json 字符串也反转为 Java Object.
但此 gson 最值得钻研的中央就是从 json 自符串到 Java Object 对象过程中, 他怎么晓得要转换成 Map<String,Book> 这种对象构造?即整个转换的实践到底是什么?
2: 咱们首先看下 TypeToken 到底是什么?
Map map1 = gson.fromJson(json, new TypeToken<Map<String,Book>>(){}.getType());
通过剖析下面代码, new TypeToken<Map<String,Book>>(){}.getType() 是实例化了一个匿名外部类对象, 并且调用了这个匿名外部类对象的 getType()办法.
要想晓得这个 getType() 返回的是什么, 咱们必须到 TypeToken 类中看下源码.
# 类申明 | |
public class TypeToken<T> { | |
final Class<? super T> rawType; | |
final Type type; | |
final int hashCode; | |
#构造函数 | |
@SuppressWarnings("unchecked") | |
protected TypeToken() {this.type = getSuperclassTypeParameter(getClass()); | |
this.rawType = (Class<? super T>) $Gson$Types.getRawType(type); | |
this.hashCode = type.hashCode();} | |
public final Type getType() {return type;} |
可见 TypeToken 是个一般的泛型类. 而 type 变量就是保留了参数化类型对象. 见下图. 其实 type 就是 ParameterizedType 类型对象 理论实现类为 sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.
通过该对象能够获取泛型的理论对象, | |
p.getActualTypeArguments(); | |
p.getRawType() |
通过下面两个办法, 就能够获取泛型的理论类型 即:
java.util.Map<java.lang.String,com.company.gson.Main$Book>
理论就是咱们匿名外部类传入的想要转成的 Java Object.
题外话: 想要弄清楚 ParameterizedType 能够看下 java 里的 Type 接口的系列.
到此: 咱们能够得出结论, 咱们其实要反序列化, 须要通知 gson 反序列化后的类型是什么, 此处通过匿名外部类把泛型传入进去. gson 通过 ParameterizedType 获取到理论的类型 [见 ParameterizedType 接口的办法].
3: 持续剖析源码
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; | |
} |
入参是 json 字符传 和 typeOfT[理论是参数化类型对象, 能够获取泛型的理论类型]. 所以外围反序列化代码进入到
T object = (T) fromJson(jsonReader, typeOfT);
只看外围代码
1: 第一步 | |
TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT); | |
2: 第二步 | |
TypeAdapter<T> typeAdapter = getAdapter(typeToken); | |
3: 第三步 | |
T object = typeAdapter.read(reader); |
第一步: 是通过 TypeToken.get(typeOfT 又返回一个 TypeToken 对象, 此处能够进去看下是否还要咱们的匿名外部类对象有关系. 代码如下:
/** | |
* Gets type literal for the given {@code Type} instance. | |
*/public static TypeToken<?> get(Type type) {return new TypeToken<Object>(type); | |
} |
可见间接 new 了个 TypeToken 对象 并且把 type 间接传进去.
第二步: 是通过 typeToken 对象返回一个 TypeAdapter 对象 间接看代码.
可见外围代码是 List<TypeAdapterFactory> factories;
遍历 factories 并调用每一个工厂办法, 传入 gson 对象和 type 类型 生成对应的 TypeAdapter.
至此:gson 的核心思想也就找到了, 就是依据不同的 type,生成不同的 TypeAdapter.
以后的工厂对象有这么多
而我例子中应用的是 MapTypeAdapterFactory
找到 factories 初始化的中央.
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); |
可见 gson 给咱们枚举了所有可能用到的工厂, 依据咱们反序列化的类型, 依据工厂对象生成对应的 TypeAdapter,并进而实现反序列化.
第三步:就是通过 TypeAdapter 把 JSON 转成 Java Object 对象