(1)一个人只要自己不放弃自己,整个世界也不会放弃你.
(2)天生我才必有大用
(3)不能忍受学习之苦就一定要忍受生活之苦,这是多么痛苦而深刻的领悟.
(4)做难事必有所得
(5)精神乃真正的刀锋
(6)战胜对手有两次,第一次在内心中.
(7)好好活就是做有意义的事情.
(8)亡羊补牢,为时未晚
(9)科技领域,没有捷径与投机取巧。
(10)有实力,一年365天都是应聘的旺季,没实力,天天都是应聘的淡季。
(11)基础不牢,地动天摇
(12)写博客初心:成长自己,辅助他人。当某一天离开人世,希望博客中的思想还能帮人指引方向.
(13)编写实属不易,若喜欢或者对你有帮助记得点赞+关注或者收藏哦~
Gson原理
文章目录
- Gson原理
- 1.Gson原理
- 1.1json分析
- 1.1.1json词法分析
- 1.1.2json语法分析
- 2.Gson的JsonElement
- 2.1Json的JsonObject对象
- 2.2JSON流程简图
- 2.3JSON适配器模式
- 2.4JSON整体流程
- 2.5JSON反射机制
- 3.打赏鼓励
-
1.Gson原理
在这个序列化和反序列化的过程中,Gson充当了一个解析器的角色。
1.1json分析
(1)编写一个JSON解析器实际上就是一个方法,它的输入是一个表示JSON的字符串,输出是结构化的对应到语言本身的数据结构
(2)一般来说,解析过程包括词法分析和语法分析两个阶段
1.1.1json词法分析
(1)源码:com.google.gson.stream.JsonToken
- BEGIN_OBJECT({)
- END_OBJECT(})
- BEGIN_ARRAY([)
- END_ARRAY(])
- NULL(null)
- NUMBER(数字)
- STRING(字符串)
- BOOLEAN(true/false)
- SEP_COLON(:)
- SEP_COMMA(,)
1.1.2json语法分析
n ➔ null
t ➔ true
f ➔ false
" ➔ string
0-9/- ➔ number
[ ➔ array
{ ➔ object
(1)json解析是基于事件驱动的
(2)全量解析
2.Gson的JsonElement
(1)该类是一个抽象类,代表着json串的某一个元素。
(2)这个元素可以是一个Json(JsonObject)、可以是一个数组(JsonArray)、可以是一个Java的基本类型(JsonPrimitive)、当然也可以为null(JsonNull);JsonObject,JsonArray,JsonPrimitive,JsonNull都是JsonElement这个抽象类的子类。
(3)它代表的是词法分析出来的每一个元素
(4)它的实现类
2.1Json的JsonObject对象
(1)JsonObject对象可以看成 name/values的集合,而这些values就是一个个JsonElement,他们的结构可以用如下图表示
2.2JSON流程简图
2.3JSON适配器模式
(1)见com.google.gson.TypeAdapter的read与write方法
(2)
任何一种数据类型的读写都有具体的TypeAdapter适配器与之对应。
(3)如果类型太多,需要自定义的TypeAdapter太多,则可考虑使用com.google.gson.internal.bind.ReflectiveTypeAdapterFactory解决
(4)com.google.gson.TypeAdapterFactory#create
根据不同的类型创建TypeAdapter
public interface TypeAdapterFactory {
<T> TypeAdapter<T> create(Gson gson, TypeToken<T> type);
}
(5)com.google.gson.reflect.TypeToken#TypeToken()
- 获取gson泛型 T 的类型
- 通过反射去创建TypeAdapter
protected TypeToken() {
this.type = getSuperclassTypeParameter(getClass());
this.rawType = (Class<? super T>) $Gson$Types.getRawType(type);
this.hashCode = type.hashCode();
}
2.4JSON整体流程
(1)Gson对象创建使用的是门面模式。
(2)而排除器使用的是代理模式
com.google.gson.internal.Excluder
(3)字段命名策略使用的是策略模式
com.google.gson.FieldNamingStrategy#translateName
(4)实例构造器
com.google.gson.internal.ConstructorConstructor
根据不同的数据类型返回一个构造器。
(5)TypeAdapter的工厂列表
List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
决定json的解析顺序
jsonstr — > 排除器---->自定义TypeAdapter—>gson自带的TypeAdapter----> 反射ReflectiveTypeAdapterFactory解析。
(6)GsonBuilder的创建
- 使用的是建造者模式
- 最终通过create方法创建Gson对象出来
(7)toJson()
com.google.gson.Gson#toJson(java.lang.Object, java.lang.reflect.Type, com.google.gson.stream.JsonWriter)
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);
} catch (AssertionError e) {
AssertionError error = new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage());
error.initCause(e);
throw error;
} finally {
writer.setLenient(oldLenient);
writer.setHtmlSafe(oldHtmlSafe);
writer.setSerializeNulls(oldSerializeNulls);
}
}
(8)JsonWriter
写操作类
(9)fromJson
public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
boolean isEmpty = true;
boolean oldLenient = reader.isLenient();
reader.setLenient(true);
try {
reader.peek();
isEmpty = false;
TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);
TypeAdapter<T> typeAdapter = getAdapter(typeToken);
T object = typeAdapter.read(reader);
return object;
} catch (EOFException e) {
if (isEmpty) {
return null;
}
throw new JsonSyntaxException(e);
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
} catch (IOException e) {
throw new JsonSyntaxException(e);
} catch (AssertionError e) {
AssertionError error = new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage());
error.initCause(e);
throw error;
} finally {
reader.setLenient(oldLenient);
}
}
(10)JsonReader
(11)getAdapter()
(12)调用TypeAdapter的read方法
2.5JSON反射机制
com.google.gson.internal.bind.ReflectiveTypeAdapterFactory#create
其他的解析器都没办法解析的时候,会使用这种反射的解析器来解析。
@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;
}
ObjectConstructor<T> constructor = constructorConstructor.get(type);
return new Adapter<T>(constructor, getBoundFields(gson, type, raw));
}
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) {
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());
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;
BoundField boundField = createBoundField(context, field, name,
TypeToken.get(fieldType), serialize, deserialize);
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;
}
(1)解析的流程重要的部分都将其定义为TypeAdapter,即每一种类型与gson之间都会有一个TypeAdapter进行桥接。
(2)如果所有的TypeAdapter都不适配,会通过ReflectiveTypeAdapter去适配任意类型。
(3)拿到具体的typeAdapter
(4)拿到之后进行字符串的解析操作。
通过反射的方式去对字符串进行解析的时候,是拿到每一个field之后,通过递归操作运用反射去完成赋值。
3.打赏鼓励
感谢您的细心阅读,您的鼓励是我写作的不竭动力!!!
3.1微信打赏
3.2支付宝打赏
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)