文章目录
1 MainActivity.kt
data class Person(val name: String,val age: Int)
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val person = Gson().fromJson("{"name":"gerry","age":18}", Person::class.java)
}
}
2 Gson.java
public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException {
Object object = fromJson(json, (Type) classOfT);
return Primitives.wrap(classOfT).cast(object);
}
public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException {
if (json == null) {
return null;
}
StringReader reader = new StringReader(json);
T target = (T) fromJson(reader, typeOfT);
return target;
}
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;
}
public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
// ... 省略其他代码
TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);
// 第一步 getAdapter 获取适配器
TypeAdapter<T> typeAdapter = getAdapter(typeToken);
// 第二步 read 创建对象并给对象赋值
T object = typeAdapter.read(reader);
// 第三步返回对象
return object;
}
3 getAdapter 获取适配器
public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {
// ..... 这里省略了一些读缓存的重要代码,具体见目录5的介绍
// 3.1 这个 factories是什么?
for (TypeAdapterFactory factory : factories) {
// 3.2 这个 factory.create 如何创建的?
TypeAdapter<T> candidate = factory.create(this, type);
if (candidate != null) {
// call 其实是 candidate 的代理类
call.setDelegate(candidate);
typeTokenCache.put(type, candidate);
return candidate;
}
}
// .....
}
3.1 这个 factories是什么?
是一个 TypeAdapterFactory 集合,在Gson创建时就被添加了各种Factory,具体如下图所示
final List<TypeAdapterFactory> factories;
// 下面开始添加各种 TypeAdapterFactory
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);
// users' type adapters 如果我们有自定义的 TypeAdapterFactory 会在这里被提前添加,为什么会这么靠前?
// 因为遍历集合时会首先找到自定义的TypeAdapterFactory
factories.addAll(factoriesToBeAdded);
// 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);
// 核心工厂类! 我们自定义的类(例如本例的 Person) 都是靠这个ReflectiveTypeAdapterFactory创建
// constructorConstructor 是 Gson成员变量 类型是 ConstructorConstructor.java
factories.add(new ReflectiveTypeAdapterFactory(
constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory));
this.factories = Collections.unmodifiableList(factories);
3.2 这个 factory.create 如何创建的?
我们知道了factory.create 中的 factory 其实是 ReflectiveTypeAdapterFactory.java
@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!
}
// 3.3 ObjectConstructor是什么?
ObjectConstructor<T> constructor = constructorConstructor.get(type);
// 3.4 getBoundFields 是什么?
// 返回的是 ReflectiveTypeAdapterFactory.java 中的 静态内部类 Adapter
return new Adapter<T>(constructor, getBoundFields(gson, type, raw));
}
3.3 ObjectConstructor是什么?
由3.1知道 constructorConstructor 是 Gson成员变量 类型是 ConstructorConstructor.java
通过调用 construct() 方法反射创建无参对象 (这里搞明白了对象是怎么创建的)
public <T> ObjectConstructor<T> get(TypeToken<T> typeToken) {
final Type type = typeToken.getType();
final Class<? super T> rawType = typeToken.getRawType();
// instanceCreators 默认为空Map,因此省略相关代码 ....
// newDefaultConstructor 创建普通的对象,重点要看这个
ObjectConstructor<T> defaultConstructor = newDefaultConstructor(rawType);
if (defaultConstructor != null) {
return defaultConstructor;
}
// newDefaultImplementationConstructor创建 Map and List and their subtypes
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();
if (!constructor.isAccessible()) {
accessor.makeAccessible(constructor);
}
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);
} 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;
}
}
3.4 getBoundFields 是什么?
返回的是一个Map,其中key是字段名(或别名),value是 ReflectiveTypeAdapterFactory.BoundField
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) {
// 先找此类的所有字段(public protected private 但不包括父类的字段)
Field[] fields = raw.getDeclaredFields();
for (Field field : fields) {
boolean serialize = excludeField(field, true);
boolean deserialize = excludeField(field, false);
if (!serialize && !deserialize) {
continue;
}
accessor.makeAccessible(field);
Type fieldType = $Gson$Types.resolve(type.getType(), raw, field.getGenericType());
// 为什么你给变量设置别名也能被识别成功? @SerializedName
// 为什么根据一个 field能获取一个集合? @SerializedName(value = "height", alternate = {"Height", "mHeight"})
// 因为考虑到了多种属性名对应一种字段的情况
List<String> fieldNames = getFieldNames(field);
BoundField previous = null;
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
// 4.1 createBoundField 是什么?
BoundField boundField = createBoundField(context, field, name,
TypeToken.get(fieldType), serialize, deserialize);
// 如果之前没有存过这个field 则返回为null,否则返回非null
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()));
raw = type.getRawType();
}
return result;
}
这段代码是使用反射来解析一个类的字段,并创建相应的 BoundField
对象,然后将这些对象存储在一个 LinkedHashMap<String, BoundField>
中。这个映射的键是字段的名称,值是与字段相关联的 BoundField
对象。
具体步骤如下:
-
创建一个空的
LinkedHashMap
,用于存储字段名和对应的BoundField
对象。 -
如果给定的类是一个接口,直接返回空的映射,因为接口一般不包含实例字段。
-
获取类的类型信息,然后进入一个循环,该循环会遍历当前类及其父类的所有字段。
-
对于每个字段,通过一些条件判断确定是否需要进行序列化(serialize)和反序列化(deserialize)。
-
使用反射使字段可访问,并获取其类型信息。
-
获取字段名列表,因为一个字段可能有多个名字(通过注解等方式指定)。
-
遍历字段名列表,为每个名字创建一个
BoundField
对象,然后将该对象添加到映射中。 -
如果同一个字段有多个名字,则会抛出
IllegalArgumentException
。 -
更新当前类的类型信息为其父类的类型信息,以便迭代到父类的字段。
-
重复上述步骤,直到达到
Object
类为止。 -
返回最终的字段映射。
4 read 创建对象并给对象赋值
根据 3.2 返回的是 ReflectiveTypeAdapterFactory.java 中的 静态内部类 Adapter
@Override public T read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
// 毫不意外调用了 3.3 中的construct()反射创建无参对象
T instance = constructor.construct();
try {
in.beginObject();
while (in.hasNext()) {
String name = in.nextName();
BoundField field = boundFields.get(name);
if (field == null || !field.deserialized) {
in.skipValue();
} else {
// 遍历每一个字段,然后执行BoundField.read方法给字段赋值
field.read(in, instance);
}
}
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
in.endObject();
return instance;
}
4.1 createBoundField 是什么?
ReflectiveTypeAdapterFactory.BoundField
private ReflectiveTypeAdapterFactory.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...
// 在这里你可以使用 JsonAdapter注解自定义 TypeAdapter
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);
// 这里注意下,我们本身就是在找Person类的getAdapter,如果Person中某个字段也是Person类怎么办?
// 岂不是会陷入嵌套调用? 3 getAdapter 获取适配器中的 calls 就是解决这个问题的
if (mapped == null) mapped = context.getAdapter(fieldType);
final TypeAdapter<?> typeAdapter = mapped;
return new ReflectiveTypeAdapterFactory.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 {
// 核心在这里, 4.2 typeAdapter.read(reader)
Object fieldValue = typeAdapter.read(reader);
if (fieldValue != null || !isPrimitive) {
field.set(value, fieldValue);
}
}
@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
}
};
}
4.2 typeAdapter.read 如何工作?
根据3.4 所示 其实每个字段都对应一个 BoundField
- 假设现在有个字段是 name:String, 根据 4.1的 context.getAdapter(fieldType) 和 3.1 的 factories.add(TypeAdapters.STRING_FACTORY)
public static final TypeAdapterFactory STRING_FACTORY = newFactory(String.class, STRING);
public static final TypeAdapter<String> STRING = new TypeAdapter<String>() {
@Override
public String read(JsonReader in) throws IOException {
JsonToken peek = in.peek();
if (peek == JsonToken.NULL) {
in.nextNull();
return null;
}
/* coerce booleans to strings for backwards compatibility */
if (peek == JsonToken.BOOLEAN) {
return Boolean.toString(in.nextBoolean());
}
return in.nextString();
}
@Override
public void write(JsonWriter out, String value) throws IOException {
out.value(value);
}
};
- 假设现在有个字段是 age:Int, 根据 4.1的 context.getAdapter(fieldType) 和 3.1 的 factories.add(TypeAdapters.INTEGER_FACTORY)
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);
}
};
5 时序图总结
注意蓝色区域,这里有可能存在递归调用的风险, 我们来举例说明
public class Student{
private int age;
private String name;
private Student friend; // 有一个同类型的属性
}
如源码和上图所示,
- 第一次对 Student类 getAdapter 时 factory.create遍历其字段发现了 friend字段也是Student类
- 第二次对 Student类 getAdapter 时 factory.create遍历其字段发现了又发现了 friend字段也是Student类
- 第三次对 Student类 getAdapter 时 factory.create遍历其字段发现了又发现了 friend字段也是Student类
- … 重复上述步骤造成递归调用
Gson是如何解决这种问题的呢 ? 缓存 + 代理
public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {
// 第一层缓存
//typeTokenCache 是 Gson内部的成员变量 (类型 ConcurrentHashMap<TypeToken<?>, TypeAdapter<?>>())
TypeAdapter<?> cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type);
if (cached != null) {
return (TypeAdapter<T>) cached;
}
// 第二层缓存 以防线程不安全,这里使用了ThreadLocal
// calls 是 Gson内部的成员变量 (类型 ThreadLocal<Map<TypeToken<?>, FutureTypeAdapter<?>>>) 用来防止递归调用 getAdapter
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
// 如果之前已经找到了Student类的adapter就直接使用缓存 FutureTypeAdapter, 只要不调用 factory.create就不会遍历字段了
FutureTypeAdapter<T> ongoingCall = (FutureTypeAdapter<T>) threadCalls.get(type);
if (ongoingCall != null) {
return ongoingCall;
}
try {
FutureTypeAdapter<T> call = new FutureTypeAdapter<T>();
// 放入threadCalls 缓存
threadCalls.put(type, call);
for (TypeAdapterFactory factory : factories) {
// 遍历该类的所有字段,找对应的Adapter
TypeAdapter<T> candidate = factory.create(this, type);
if (candidate != null) {
// 后续同类型直接可以根据 FutureTypeAdapter.delegate来处理
call.setDelegate(candidate);
typeTokenCache.put(type, candidate);
return candidate;
}
}
throw new IllegalArgumentException("GSON (" + GsonBuildConfig.VERSION + ") cannot handle " + type);
} finally {
threadCalls.remove(type);
if (requiresThreadLocalCleanup) {
calls.remove();
}
}
}
static class FutureTypeAdapter<T> extends TypeAdapter<T> {
private TypeAdapter<T> delegate;
public void setDelegate(TypeAdapter<T> typeAdapter) {
if (delegate != null) {
throw new AssertionError();
}
delegate = typeAdapter;
}
@Override public T read(JsonReader in) throws IOException {
if (delegate == null) {
throw new IllegalStateException();
}
// FutureTypeAdapter 本质上是代理类,还是使用Adapter来read字段
return delegate.read(in);
}
@Override public void write(JsonWriter out, T value) throws IOException {
if (delegate == null) {
throw new IllegalStateException();
}
delegate.write(out, value);
}
}
至此就把 Json -> Object的过程详细梳理了一遍, Object -> Json 也是类似,只不过把read方法换成了wirte方法。