Gson源码版本 1 2 3 4 5 <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.6</version> </dependency>
summary
抽象类TypeAdapter,委托模式,处理json字符串和特定类型对象之间的相互转换。抽象方法read和write在具体的TypeAdapter有各自的实现,比较复杂的包括集合类型的CollectionTypeAdapterFactory.Adapter(比如read时,要实例化集合,再循环处理集合内元素)、自定义对象类型的ReflectiveTypeAdapterFactory.Adapter(比如需要循环处理类内field的read和write)。
接口TypeAdapterFactory,抽象工厂模式,创建给定类型的TypeAdapter。基础类型已经预先创建typeAdapter(调用factory.create时,如果是给定的类型,返回预定义的adapter),Collection、自定义类型等包含泛型的,在运行时create(因为会有不同的要素,比如constructor、elementType、boundFields等)。
序列化时,泛型类型通过TypeAdapterRuntimeTypeWrapper进行处理。会判断使用rawType带过来的类型还是运行时真实value的类型进行后续处理。
责任链模式(?待确认)。在对顶层类型getAdapter过程中,会递归对下层类型进行getAdapter,并保存在上层adapter中;在顶层adapter.write过程中,也递归调用到子类型的adapter.write。ps在基本类型adapter中,才调用JsonReader/Writer读写。
设计模式 工厂模式 TypeAdapterFactory.create提供给定TypeToken的TypeAdapter.
1 2 3 4 5 6 7 8 public interface TypeAdapterFactory { <T> TypeAdapter<T> create (Gson gson, TypeToken<T> type) ; }
factory和adapter Gson内置factory 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>(); factories.add(TypeAdapters.JSON_ELEMENT_FACTORY); factories.add(ObjectTypeAdapter.FACTORY); factories.add(excluder); factories.addAll(typeAdapterFactories); 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); factories.add(TypeAdapters.newFactory(long .class, Long.class, longAdapter(longSerializationPolicy))); 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.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.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); factories.add(new CollectionTypeAdapterFactory(constructorConstructor)); factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization)); factories.add(new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor)); factories.add(TypeAdapters.ENUM_FACTORY); factories.add(new ReflectiveTypeAdapterFactory( constructorConstructor, fieldNamingPolicy, excluder));
newFactory typeToken.getRawType()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public static <TT> TypeAdapterFactory newFactory ( final Class<TT> type, final TypeAdapter<TT> typeAdapter) { return new TypeAdapterFactory() { @SuppressWarnings ("unchecked" ) @Override public <T> TypeAdapter<T> create (Gson gson, TypeToken<T> typeToken) { return typeToken.getRawType() == type ? (TypeAdapter<T>) typeAdapter : null ; } @Override public String toString () { return "Factory[type=" + type.getName() + ",adapter=" + typeAdapter + "]" ; } }; } public static <TT> TypeAdapterFactory newFactory ( final Class<TT> unboxed, final Class<TT> boxed, final TypeAdapter<? super TT> typeAdapter) { return new TypeAdapterFactory() { @SuppressWarnings ("unchecked" ) @Override public <T> TypeAdapter<T> create (Gson gson, TypeToken<T> typeToken) { Class<? super T> rawType = typeToken.getRawType(); return (rawType == unboxed || rawType == boxed) ? (TypeAdapter<T>) typeAdapter : null ; } @Override public String toString () { return "Factory[type=" + boxed.getName() + "+" + unboxed.getName() + ",adapter=" + typeAdapter + "]" ; } }; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public static final TypeAdapterFactory TIMESTAMP_FACTORY = new TypeAdapterFactory() { @SuppressWarnings ("unchecked" ) @Override public <T> TypeAdapter<T> create (Gson gson, TypeToken<T> typeToken) { if (typeToken.getRawType() != Timestamp.class) { return null ; } final TypeAdapter<Date> dateTypeAdapter = gson.getAdapter(Date.class); return (TypeAdapter<T>) new TypeAdapter<Timestamp>() { @Override public Timestamp read (JsonReader in) throws IOException { Date date = dateTypeAdapter.read(in); return date != null ? new Timestamp(date.getTime()) : null ; } @Override public void write (JsonWriter out, Timestamp value) throws IOException { dateTypeAdapter.write(out, value); } }; } };
CALENDAR和LOCALE的factory、adapter 可以学习
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 public static final TypeAdapter<Calendar> CALENDAR = new TypeAdapter<Calendar>() { private static final String YEAR = "year" ; private static final String MONTH = "month" ; private static final String DAY_OF_MONTH = "dayOfMonth" ; private static final String HOUR_OF_DAY = "hourOfDay" ; private static final String MINUTE = "minute" ; private static final String SECOND = "second" ; @Override public Calendar read (JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull(); return null ; } in.beginObject(); int year = 0 ; int month = 0 ; int dayOfMonth = 0 ; int hourOfDay = 0 ; int minute = 0 ; int second = 0 ; while (in.peek() != JsonToken.END_OBJECT) { String name = in.nextName(); int value = in.nextInt(); if (YEAR.equals(name)) { year = value; } else if (MONTH.equals(name)) { month = value; } else if (DAY_OF_MONTH.equals(name)) { dayOfMonth = value; } else if (HOUR_OF_DAY.equals(name)) { hourOfDay = value; } else if (MINUTE.equals(name)) { minute = value; } else if (SECOND.equals(name)) { second = value; } } in.endObject(); return new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute, second); } @Override public void write (JsonWriter out, Calendar value) throws IOException { if (value == null ) { out.nullValue(); return ; } out.beginObject(); out.name(YEAR); out.value(value.get(Calendar.YEAR)); out.name(MONTH); out.value(value.get(Calendar.MONTH)); out.name(DAY_OF_MONTH); out.value(value.get(Calendar.DAY_OF_MONTH)); out.name(HOUR_OF_DAY); out.value(value.get(Calendar.HOUR_OF_DAY)); out.name(MINUTE); out.value(value.get(Calendar.MINUTE)); out.name(SECOND); out.value(value.get(Calendar.SECOND)); out.endObject(); } }; public static final TypeAdapterFactory CALENDAR_FACTORY = newFactoryForMultipleTypes(Calendar.class, GregorianCalendar.class, CALENDAR); public static final TypeAdapter<Locale> LOCALE = new TypeAdapter<Locale>() { @Override public Locale read (JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull(); return null ; } String locale = in.nextString(); StringTokenizer tokenizer = new StringTokenizer(locale, "_" ); String language = null ; String country = null ; String variant = null ; if (tokenizer.hasMoreElements()) { language = tokenizer.nextToken(); } if (tokenizer.hasMoreElements()) { country = tokenizer.nextToken(); } if (tokenizer.hasMoreElements()) { variant = tokenizer.nextToken(); } if (country == null && variant == null ) { return new Locale(language); } else if (variant == null ) { return new Locale(language, country); } else { return new Locale(language, country, variant); } } @Override public void write (JsonWriter out, Locale value) throws IOException { out.value(value == null ? null : value.toString()); } }; public static final TypeAdapterFactory LOCALE_FACTORY = newFactory(Locale.class, LOCALE);
Enum的泛型实现 可以看下jackson的实现,以后枚举字段可以直接用枚举值,注解使用code来序列化(不过还要注意vo和po的转换,DAO层和数据库是怎么支持枚举的?)
class1.isAssignableFrom(class2) 表示 class1是class2的超类或本身
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 private static final class EnumTypeAdapter <T extends Enum <T >> extends TypeAdapter <T > { private final Map<String, T> nameToConstant = new HashMap<String, T>(); private final Map<T, String> constantToName = new HashMap<T, String>(); public EnumTypeAdapter (Class<T> classOfT) { try { for (T constant : classOfT.getEnumConstants()) { String name = constant.name(); SerializedName annotation = classOfT.getField(name).getAnnotation(SerializedName.class); if (annotation != null ) { name = annotation.value(); for (String alternate : annotation.alternate()) { nameToConstant.put(alternate, constant); } } nameToConstant.put(name, constant); constantToName.put(constant, name); } } catch (NoSuchFieldException e) { throw new AssertionError(e); } } @Override public T read (JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull(); return null ; } return nameToConstant.get(in.nextString()); } @Override public void write (JsonWriter out, T value) throws IOException { out.value(value == null ? null : constantToName.get(value)); } } public static final TypeAdapterFactory ENUM_FACTORY = new TypeAdapterFactory() { @SuppressWarnings ({"rawtypes" , "unchecked" }) @Override public <T> TypeAdapter<T> create (Gson gson, TypeToken<T> typeToken) { Class<? super T> rawType = typeToken.getRawType(); if (!Enum.class.isAssignableFrom(rawType) || rawType == Enum.class) { return null ; } if (!rawType.isEnum()) { rawType = rawType.getSuperclass(); } return (TypeAdapter<T>) new EnumTypeAdapter(rawType); } };
InetAdress和JsonElement是用超类Adapter工作的
基本类型的factory和adapter Long/Float/Double的adapter根据序列化自定义而不同
复杂类型的factory和adapter
CollectionTypeAdapterFactory 集合类型 ReflectiveTypeAdapterFactory 自定义对象 TypeAdapterRuntimeTypeWrapper 是对TypeAdapter的封装,用于write运行时判断更准确的类型。
在array/collection/map/自定义类型等adapter中使用。
比如Object a = new String(“aaa”),实际上应使用StringTypeAdapter来write。
read时,以什么样的类型赋值给a?
TypeToken 匿名内部类有两种语法格式
new 接口(){}
new 父类构造器(参数列表){} TypeToken为第二种new TypeToken<List<TwoGeneric<Integer,User>>>(){};
得到的是TypeToken<List<TwoGeneric<Integer,User>>>
的匿名子类。
$Gson$Types 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 public static Class<?> getRawType(Type type) { if (type instanceof Class<?>) { return (Class<?>) type; } else if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) type; Type rawType = parameterizedType.getRawType(); checkArgument(rawType instanceof Class); return (Class<?>) rawType; } else if (type instanceof GenericArrayType) { Type componentType = ((GenericArrayType)type).getGenericComponentType(); return Array.newInstance(getRawType(componentType), 0 ).getClass(); } else if (type instanceof TypeVariable) { return Object.class; } else if (type instanceof WildcardType) { return getRawType(((WildcardType) type).getUpperBounds()[0 ]); } else { String className = type == null ? "null" : type.getClass().getName(); throw new IllegalArgumentException("Expected a Class, ParameterizedType, or " + "GenericArrayType, but <" + type + "> is of type " + className); } }
序列化与反序列化结果类型对比
wildcard类型,根据上界反序列化。upperBoundList的上界是TestInnerObject ,?是TestInnerSonObject,反序列化丢失了innerSonId的值。lowerBoundList的上界是Object,反序列化为map
声明的类型为Object,write正常,read为map
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 @Test public void testGson () { Gson gson = new Gson(); TestInnerObject testInnerObject = new TestInnerObject(); testInnerObject.setInnerId("inner" ); TestInnerParentObject testInnerParentObject = new TestInnerParentObject(); testInnerParentObject.setInnerParentId("parent" ); TestInnerSonObject testInnerSonObject = new TestInnerSonObject(); testInnerSonObject.setInnerSonId("son" ); TestObject testObject = new TestObject(); testObject.setString("mock" ); testObject.setLongList(Lists.newArrayList(1L , 2L )); Map<String, TestInnerObject> map = Maps.newHashMap(); map.put("mockKey" , testInnerObject); testObject.setMap(map); testObject.setUpperBoundList(Lists.newArrayList(testInnerSonObject)); testObject.setLowerBoundList(Lists.newArrayList(testInnerParentObject)); testObject.setObject(testInnerSonObject); testObject.setLists(new List[]{Lists.newArrayList(testInnerObject)}); String json = gson.toJson(testObject); log.info("json = {}" , json); testObject = gson.fromJson(json, TestObject.class); log.info("testObject = {}" , testObject); } @Data public class TestObject { private String string; private List<Long> longList; private List<TestInnerObject> testInnerObjectList; private Map<String, TestInnerObject> map; private List<? extends TestInnerObject> upperBoundList; private List<? super TestInnerObject> lowerBoundList; private TestObject[] testObjectArray; private List[] lists; private Object object; } @Data public class TestInnerObject extends TestInnerParentObject { private String innerId; } @Data public class TestInnerParentObject { private String innerParentId; } @Data public class TestInnerSonObject extends TestInnerObject { private String innerSonId; }
todo
map 复杂key的序列化
map peek == JsonToken.BEGIN_ARRAY
reflectiveTypeAdapter 多个泛型 [done. read时根据name和TypeToken,write时根据TypeAdapterRuntimeTypeWrapper]
toJson时候,type里带实例的runtime type? [done. TypeAdapterRuntimeTypeWrapper处理]
JsonAdapterAnnotationTypeAdapterFactory [almost done. 获取filed上注解的TypeAdapter进行后续处理]
$Gson$Types.resolve [done]
JsonWriter和JsonReader的读写 [almost done. 写比较简单,不同类型输出;读在fillBuffer时先读到缓存中,不同类型在缓存中操作。]
read之后怎么赋值?
装箱和非装箱,都是用的装箱adapter,返回装箱类型。—-那装箱类型赋值给非装箱类型吗?用set还是set方法?
TypeToken的rawType是怎么取到的?
gson.getAdapter(Date.class)的逻辑?