java gson解析,追踪解析Gson源码(2)

接上篇

三 JsonReader 和 JsonWriter

在进行 json 的序列化和反序列化源码解析之前先了解一下其主体工具类。

1 JsonReader

JsonReader 是 Gson 中用于 json 反序列化的主体。

在 Gson 包中可以不使用 Gson 门面而单独使用 JsonReader 进行 json 的反序列化:

public static void main(String[] args){

//json 字符串

String json = "{\"name\":\"zhangsan\",\"age\":18}";

//使用 StringReader 包装字符串

StringReader strReader = new StringReader(json);

//使用 JsonReader 包装 StringReader

JsonReader jsonReader = new JsonReader(strReader);

//创建一个参数均为空的目标对象

Person p = new Person();

try {

//beginObject(...) 方法用于告诉 jsonReader 开始读取一个 object

jsonReader.beginObject();

//while 循环读取

while(jsonReader.hasNext()){

//读取一个 json 的 key 值

String name = jsonReader.nextName();

switch (name){

case "name":

p.setName(jsonReader.nextString()); //读取一个 String 作为 value,存入对象中

break;

case "age":

p.setAge(jsonReader.nextInt()); //读取一个 int 作为 value,存入对象中

break;

}

}

jsonReader.endObject();

} catch (IOException e) {

e.printStackTrace();

}

System.out.println("名字:" + p.getName());

System.out.println("年龄:" +p.getAge())

}

JsonReader 的构造方法:

//JsonReader.class

public JsonReader(Reader in) {

if (in == null) {

throw new NullPointerException("in == null");

}

//传入的 Reader 中保存着要读取的 json 主体

//此处比较常用的是 StringReader,但是也可以是 FileReader 等其它 Reader 接口的实现类

this.in = in;

}

JsonReader 仅此一个构造方法,创建对象均调用此方法。

先来看一下 JsonReader 中非常重要的一个非公开方法 doPeek():

//JsonReader.class

int doPeek() throws IOException {

//stack 是一个定义在 JsonReader 中的 int 数组,作为 JsonReader 的指令集存在,用于控制变量 peeked 的状态

//在 JsonReader 初始化的时候会将 stack 的第一个元素变成6,其余均为0

//6的意思根据官方注释为 "No object or array has been started"(还没开始读取对象或列表)

//6作为常量保存在 JsonScope 中,JsonScope 中还保存了很多代表指令的常量,下列会用到

//stackSize 是 stack 的有效元素计数器,初始化时 stackSize = 1,即只有第一个元素是有效的

int peekStack = stack[stackSize - 1];

//JsonScope.EMPTY_ARRAY = 1

if (peekStack == JsonScope.EMPTY_ARRAY) {

//JsonScope.NONEMPTY_ARRAY = 2

stack[stackSize - 1] = JsonScope.NONEMPTY_ARRAY;

} else if (peekStack == JsonScope.NONEMPTY_ARRAY) {

//在第一次调用 nextNonWhitespace(true) 方法的时候,json 字符串会被转存为一个 char 数组

//该方法以 int 值的形式返回下一个要解析的 char 对象

int c = nextNonWhitespace(true);

switch (c) {

case ']':

//peeked 是 JsonReader 中最重要的用来状态控制的 int 变量

//peeker 和 stack 会协同控制 JsonReader 的逻辑行为

return peeked = PEEKED_END_ARRAY; //PEEKED_END_ARRAY = 4

case ';':

//检查标准协议选项,json 标准中的符号没有分号

//所以在 lenient = false 的时候就会报错

checkLenient();

case ',':

break;

default:

throw syntaxError("Unterminated array");

}

//JsonScope.EMPTY_OBJECT = 3,JsonScope.NONEMPTY_OBJECT = 5

} else if (peekStack == JsonScope.EMPTY_OBJECT || peekStack == JsonScope.NONEMPTY_OBJECT) {

//JsonScope.DANGLING_NAME = 4

stack[stackSize - 1] = JsonScope.DANGLING_NAME;

if (peekStack == JsonScope.NONEMPTY_OBJECT) {

int c = nextNonWhitespace(true);

switch (c) {

case '}':

return peeked = PEEKED_END_OBJECT; //PEEKED_END_OBJECT = 2

case ';':

checkLenient();

case ',':

break;

default:

throw syntaxError("Unterminated object");

}

}

int c = nextNonWhitespace(true);

switch (c) {

case '"':

return peeked = PEEKED_DOUBLE_QUOTED_NAME; //PEEKED_DOUBLE_QUOTED_NAME = 13

case '\'':

checkLenient();

return peeked = PEEKED_SINGLE_QUOTED_NAME; //PEEKED_SINGLE_QUOTED_NAME = 12

case '}':

if (peekStack != JsonScope.NONEMPTY_OBJECT) {

return peeked = PEEKED_END_OBJECT;

} else {

throw syntaxError("Expected name");

}

default:

checkLenient();

pos--;

if (isLiteral((char) c)) {

return peeked = PEEKED_UNQUOTED_NAME; //PEEKED_UNQUOTED_NAME = 14

} else {

throw syntaxError("Expected name");

}

}

} else if (peekStack == JsonScope.DANGLING_NAME) {

stack[stackSize - 1] = JsonScope.NONEMPTY_OBJECT;

int c = nextNonWhitespace(true);

switch (c) {

case ':':

break;

case '=':

checkLenient();

//buffer 是储存 json 字符串的 char 数组

//pos 是已经读取到字符的数量指针

//limit 是 buffer 的可用部分的总长

if ((pos < limit || fillBuffer(1)) && buffer[pos] == '>') {

pos++;

}

break;

default:

throw syntaxError("Expected ':'");

}

//JsonScope.EMPTY_DOCUMENT = 6

//第一次进入方法的时候,会进入这个 if 语句中

} else if (peekStack == JsonScope.EMPTY_DOCUMENT) {

//检查标准化协议相关

if (lenient) {

consumeNonExecutePrefix();

}

//JsonScope.NONEMPTY_DOCUMENT = 7

stack[stackSize - 1] = JsonScope.NONEMPTY_DOCUMENT;

} else if (peekStack == JsonScope.NONEMPTY_DOCUMENT) {

int c = nextNonWhitespace(false);

if (c == -1) {

return peeked = PEEKED_EOF;

} else {

checkLenient();

pos--;

}

//JsonScope.CLOSED = 8

} else if (peekStack == JsonScope.CLOSED) {

throw new IllegalStateException("JsonReader is closed");

}

//在这里获取到了下一个要解析的 char 的 int 值

int c = nextNonWhitespace(true);

//进入 switch 去进行定位,定位到了之后修改 peeked 的状态

switch (c) {

case ']':

if (peekStack == JsonScope.EMPTY_ARRAY) {

return peeked = PEEKED_END_ARRAY;

}

case ';':

case ',':

if (peekStack == JsonScope.EMPTY_ARRAY || peekStack == JsonScope.NONEMPTY_ARRAY) {

checkLenient();

pos--;

return peeked = PEEKED_NULL;

} else {

throw syntaxError("Unexpected value");

}

case '\'':

checkLenient();

return peeked = PEEKED_SINGLE_QUOTED;

case '"':

return peeked = PEEKED_DOUBLE_QUOTED;

case '[':

return peeked = PEEKED_BEGIN_ARRAY;

case '{':

return peeked = PEEKED_BEGIN_OBJECT;

default:

pos--;

}

//peekKeyword() 方法会从 buffer 数组里获取下一个 char

//然后根据这个字符判断下一个要处理的字符串是不是 true、false、null 等特殊字符

//如果不是,会返回 result = PEEKED_NONE

int result = peekKeyword();

if (result != PEEKED_NONE) {

//不等于 PEEKED_NONE,证明下一个确实是特殊字符

return result;

}

//peekNumber() 方法和上述 peekKeyword() 方法很类似

//用于判断下一个要处理的字符串是否是数字

result = peekNumber();

if (result != PEEKED_NONE) {

return result;

}

//isLiteral(buffer[pos]) 用于判断下一个字符是否是特殊符

//比如 换行符、井号、括号 等

//如果是 换行符 的话这里就会抛出错误

if (!isLiteral(buffer[pos])) {

throw syntaxError("Expected value");

}

checkLenient();

return peeked = PEEKED_UNQUOTED; //PEEKED_UNQUOTED = 10

}

方法虽然比较长,但是代码其实比较简单,本质上是根据 stack 指令去修改 peeked 的值,从而达到状态控制的效果。

再来看 beginObject() 方法:

//JsonReader.class

public void beginObject() throws IOException {

int p = peeked;

//初始化时 peeked = PEEKED_NONE

//在 doPeek() 方法中会修改成 PEEKED_BEGIN_OBJECT,即开始一个 Object 的序列化

if (p == PEEKED_NONE) {

p = doPeek();

}

if (p == PEEKED_BEGIN_OBJECT) {

//push(...) 方法会检查 stack 数组的容积,适时进行扩容,并把传入的指令存放到数组中

//此处将 EMPTY_OBJECT 指令存入到 stack 中

push(JsonScope.EMPTY_OBJECT);

//将 peeked 状态初始化

peeked = PEEKED_NONE;

} else {

throw new IllegalStateException("Expected BEGIN_OBJECT but was " + peek() + locationString());

}

}

再来看 nextName() 方法:

//JsonReader.class

public String nextName() throws IOException {

//老样子进行 peeked 的状态获取

int p = peeked;

if (p == PEEKED_NONE) {

p = doPeek();

}

String result;

//在这里通过 if 语句和 peeked 定位 json 的 key 是用单引号还是双引号包裹的

//result 就是 key 的字符串

if (p == PEEKED_UNQUOTED_NAME) {

result = nextUnquotedValue();

} else if (p == PEEKED_SINGLE_QUOTED_NAME) {

result = nextQuotedValue('\'');

} else if (p == PEEKED_DOUBLE_QUOTED_NAME) {

result = nextQuotedValue('"');

} else {

throw new IllegalStateException("Expected a name but was " + peek() + locationString());

}

//将 peeked 状态初始化

peeked = PEEKED_NONE;

//pathNames 是一个用来储存所有 key 的字符串的数组

pathNames[stackSize - 1] = result;

return result;

}

nextQuotedValue(...) 方法里实际上是比较繁琐的字符串处理,在这里暂时不展开了。

hasNext() 和 nextString() 方法其实都和 nextName() 方法差不多,本质上都是根据 peeked 的值去进入不同的 if 语句来处理字符串。

2 JsonWriter

JsonWriter 是 Gson 中用于 json 序列化的主体。

和 JsonReader 一样,也可以不使用 Gson 门面而单独使用 JsonWriter 进行 json 的序列化:

public static void main(String[] args){

//组装 bean

Person person = new Person();

person.setName("zhangsan");

person.setAge(18);

//创建一个 StringWriter,本质是 StringBuffer 的封装

StringWriter writer = new StringWriter();

//用 JsonWriter 去封装 StringWriter

JsonWriter jsonWriter = new JsonWriter(writer);

try {

//启动一个 object 的写入

jsonWriter.beginObject();

//写入 key-value

jsonWriter.name("name").value(person.getName());

jsonWriter.name("age").value(person.getAge());

//结束命令

jsonWriter.endObject();

//将 JsonWriter 里的数据存入到 StringWriter 中

jsonWriter.flush();

} catch (IOException e) {

e.printStackTrace();

}

System.out.println(writer.toString());

}

JsonWriter 的构造方法:

//JsonWriter.class

public JsonWriter(Writer out) {

if (out == null) {

throw new NullPointerException("out == null");

}

this.out = out;

}

追踪一下 beginObject() 方法:

//JsonWriter.class

public JsonWriter beginObject() throws IOException {

//这个方法主要的作用是在不同的 object 之间加逗号

//如果是起始第一个 object 就不需要了,会直接跳过

writeDeferredName();

return open(EMPTY_OBJECT, "{");

}

继续追踪 open(...) 方法:

//JsonWriter.class

private JsonWriter open(int empty, String openBracket) throws IOException {

//该方法会使用 stack 中最新的指令进行操作

beforeValue();

//push(...) 方法会检查 stack 数组的容积,适时进行扩容,并把传入的指令存放到数组中

push(empty);

//写入字符串

out.write(openBracket);

return this;

}

JsonWriter 中没有 JsonReader 中那么复杂的指令操作,所以没有引入 peeked 变量,仅仅使用 stack 数组来控制状态。

stack 的控制封装在 beforeValue() 方法中:

//JsonWriter.class

private void beforeValue() throws IOException {

//peek() 方法会根据 stack 数组的指令获取到下一个要操作的字符类型

switch (peek()) {

case NONEMPTY_DOCUMENT:

if (!lenient) {

throw new IllegalStateException(

"JSON must have only one top-level value.");

}

case EMPTY_DOCUMENT:

//replaceTop(...) 方法会将 stack 最新的指令更新成传入的参数

replaceTop(NONEMPTY_DOCUMENT);

break;

case EMPTY_ARRAY:

replaceTop(NONEMPTY_ARRAY);

//换行

newline();

break;

case NONEMPTY_ARRAY:

out.append(',');

newline();

break;

case DANGLING_NAME:

//separator 即为 ":" (冒号)

out.append(separator);

replaceTop(NONEMPTY_OBJECT);

break;

default:

throw new IllegalStateException("Nesting problem.");

}

}

来看一下 name(...) 方法:

//JsonWriter.class

public JsonWriter name(String name) throws IOException {

if (name == null) {

throw new NullPointerException("name == null");

}

if (deferredName != null) {

throw new IllegalStateException();

}

if (stackSize == 0) {

throw new IllegalStateException("JsonWriter is closed.");

}

//这一行代码中会暂时将传入的 name 参数保存在一个全局变量中,

//所以 JsonWriter 在调用 value(...) 方法之前不能再调用 name(...) 方法了,不然在上方的判断中会报错

deferredName = name;

return this;

}

来看一下 value(...) 方法:

//JsonWriter.class

public JsonWriter value(String value) throws IOException {

if (value == null) {

//nullValue() 方法会在 value 值的地方存入一个 null

return nullValue();

}

//这一方法会将 之前保存在 deferredName 中的字符串写入到 writer 中

//方法中会处理加逗号、将 deferredName 变量清空等问题

//核心是调用 string(...) 方法写入

writeDeferredName();

//更新 stack 指令

beforeValue();

//和上方写入 deferredName 一样,此处调用写入 value

string(value);

return this;

}

总的来说 JsonWriter 比 JsonReader 简单,简要描述一下不过多展开。

四 JSON 字符串转 Bean

该 part 的起点:

Person person = gson.fromJson(json,Person.class);

追踪 fromJson(...) 方法:

//Gson.class

public T fromJson(String json, Class classOfT) throws JsonSyntaxException {

//将字符串转成 object 的主体方法

//3.1

Object object = fromJson(json, (Type) classOfT);

return Primitives.wrap(classOfT).cast(object);

}

先来看一下上述的第二行代码:

return Primitives.wrap(classOfT).cast(object);

Primitives.wrap(...) 方法的实现:

//Primitives.class

public static Class wrap(Class type) {

//PRIMITIVE_TO_WRAPPER_TYPE 是一个 map 对象

//$Gson$Preconditions.checkNotNull(...) 用来效验 type 不为空

@SuppressWarnings("unchecked")

Class wrapped = (Class) PRIMITIVE_TO_WRAPPER_TYPE.get(

$Gson$Preconditions.checkNotNull(type));

//如果 map 中不存在 type 为 key 的值,则返回 type,否则返回取到的 value

return (wrapped == null) ? type : wrapped;

}

PRIMITIVE_TO_WRAPPER_TYPE 是一个定义在 Primitives 中的 map 对象:

//Primitives.class

private static final Map, Class>> PRIMITIVE_TO_WRAPPER_TYPE;

PRIMITIVE_TO_WRAPPER_TYPE 中主要存放了 float、int、double 等原始类型的 class:

//Primitives.class

static {

Map, Class>> primToWrap = new HashMap, Class>>(16);

Map, Class>> wrapToPrim = new HashMap, Class>>(16);

//以下代码是将原始类型和包装类型存入两个 map 的过程

add(primToWrap, wrapToPrim, boolean.class, Boolean.class);

add(primToWrap, wrapToPrim, byte.class, Byte.class);

add(primToWrap, wrapToPrim, char.class, Character.class);

add(primToWrap, wrapToPrim, double.class, Double.class);

add(primToWrap, wrapToPrim, float.class, Float.class);

add(primToWrap, wrapToPrim, int.class, Integer.class);

add(primToWrap, wrapToPrim, long.class, Long.class);

add(primToWrap, wrapToPrim, short.class, Short.class);

add(primToWrap, wrapToPrim, void.class, Void.class);

//Collections.unmodifiableMap(...) 返回一个只能阅读不能修改的 map

//原始类型作为 key,包装类型作为 value

PRIMITIVE_TO_WRAPPER_TYPE = Collections.unmodifiableMap(primToWrap);

//包装类型作为 value,原始类型作为 key

WRAPPER_TO_PRIMITIVE_TYPE = Collections.unmodifiableMap(wrapToPrim);

}

由此可见 Primitives.wrap(...) 本质上是判断传入的 type 是否是原始类型,如果是,则会转换成包装类型并返回。

至于 Primitives.wrap(classOfT).cast(object) 中的 cast(...),则是定义在 Class 中的方法:

//Class.class

@HotSpotIntrinsicCandidate

public T cast(Object obj) {

//isInstance(...) 方法等价于关键词 instanceof

//如果 obj 不为 null 且 不为该 Class 对象的子类,则会抛出错误

if (obj != null && !isInstance(obj))

throw new ClassCastException(cannotCastMsg(obj));

return (T) obj;

}

代码比较简单,本质上就是强转类型。

再来看这行代码:

Object object = fromJson(json, (Type) classOfT);

追踪具体实现:

//Gson.class

public T fromJson(String json, Type typeOfT) throws JsonSyntaxException {

//非 null 判断

if (json == null) {

return null;

}

//StringReader 是一个 jdk 中存在的 String 和 Reader 的关联封装类

StringReader reader = new StringReader(json);

//主体功能实现方法

T target = (T) fromJson(reader, typeOfT);

//返回一个指定泛型的对象

return target;

}

继续追踪重载方法:

//Gson.class

public T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException {

//初始化一个 JsonReader

JsonReader jsonReader = newJsonReader(json);

//主体功能实现方法

T object = (T) fromJson(jsonReader, typeOfT);

//在整个反序列化过程结束之前效验 jsonReader 的 peeked 的状态

//如果 peeker 未处于结束状态,则会报错

assertFullConsumption(object, jsonReader);

return object;

}

继续追踪重载方法:

//Gson.class

public T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {

boolean isEmpty = true;

boolean oldLenient = reader.isLenient();

//打开 reader 的标准化检验

reader.setLenient(true);

try {

//此处相当于调用了一次 JsonReader 中的 doPeek() 方法

reader.peek();

isEmpty = false;

//TypeToken 本质上是 Class 的增强封装类

TypeToken typeToken = (TypeToken) TypeToken.get(typeOfT);

//根据 TypeToken 获取对应的能够处理其类型的 TypeAdapter

TypeAdapter typeAdapter = getAdapter(typeToken);

//反射创建 object

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) {

throw new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage(), e);

} finally {

reader.setLenient(oldLenient);

}

}

先来看一下 getAdapter(...) 方法:

//Gson.class

public TypeAdapter getAdapter(TypeToken type) {

//typeTokenCache 是 Gson 中的一个 map 对象,用于储存 TypeAdapter

//typeTokenCache 是一个 Gson 中各个线程公用的一个缓存池

TypeAdapter> cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type);

if (cached != null) {

//如果本身就有储存了,就直接返回

return (TypeAdapter) cached;

}

//calls 是一个 ThreadLocal 对象

//ThreadLocal 是 Gson 中单个线程使用的缓存池,在里面存入的对象会在 finally 代码块中清空掉

Map, FutureTypeAdapter>> threadCalls = calls.get();

//判断是否需要清空 ThreadLocal

boolean requiresThreadLocalCleanup = false;

if (threadCalls == null) {

threadCalls = new HashMap, FutureTypeAdapter>>();

calls.set(threadCalls);

//这里存入了对象,所以需要清空 ThreadLocal

requiresThreadLocalCleanup = true;

}

//如果存在对象,就会在这里取用出来并返回

//FutureTypeAdapter 是一个门面模式的应用,其实本质是使用内部的 TypeAdapter 去处理业务

//如果内部没有存入实际处理业务的 TypeAdapter,就会报错

FutureTypeAdapter ongoingCall = (FutureTypeAdapter) threadCalls.get(type);

if (ongoingCall != null) {

return ongoingCall;

}

try {

FutureTypeAdapter call = new FutureTypeAdapter();

threadCalls.put(type, call);

//这个方法的主体是这个 for 循环,用于从 Gson 初始化的时候储存的列表中获取到对应的 TypeAdapter

for (TypeAdapterFactory factory : factories) {

//TypeAdapter 的 create(...) 方法对于不是对应类型的参数会返回 null

TypeAdapter candidate = factory.create(this, type);

if (candidate != null) {

//在此处会存入业务处理的 TypeAdapter

call.setDelegate(candidate);

//在此处存入公用缓存

typeTokenCache.put(type, candidate);

return candidate;

}

}

throw new IllegalArgumentException("GSON (" + GsonBuildConfig.VERSION + ") cannot handle " + type);

} finally {

//清除 ThreadLocal 缓存

threadCalls.remove(type);

if (requiresThreadLocalCleanup) {

calls.remove();

}

}

}

到此为止 json 的反序列化就基本完毕了.

五 Bean 转 JSON 字符串

该 part 的起点:

String json2 = gson.toJson(person);

追踪 toJson(...) 方法:

//Gson.class

public String toJson(Object src) {

if (src == null) {

return toJson(JsonNull.INSTANCE);

}

return toJson(src, src.getClass());

}

toJson(JsonNull.INSTANCE) 方法最后会输出一个 null 字符串,不多展开了。

继续来关注下方主要实现逻辑:

//Gson.class

public String toJson(Object src, Type typeOfSrc) {

//新建一个 StringWriter

StringWriter writer = new StringWriter();

//主要逻辑

toJson(src, typeOfSrc, writer);

//返回

return writer.toString();

}

继续追踪主要逻辑方法:

//Gson.class

public void toJson(Object src, Type typeOfSrc, Appendable writer) throws JsonIOException {

try {

//这里将 StringWriter 包装成了 JsonWriter

JsonWriter jsonWriter = newJsonWriter(Streams.writerForAppendable(writer));

//主要逻辑

toJson(src, typeOfSrc, jsonWriter);

} catch (IOException e) {

throw new JsonIOException(e);

}

}

继续追踪主要逻辑方法:

//Gson.class

public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOException {

//获取适配的 TypeAdapter

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) adapter).write(writer, src);

} catch (IOException e) {

throw new JsonIOException(e);

} catch (AssertionError e) {

throw new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage(), e);

} finally {

//还原

writer.setLenient(oldLenient);

writer.setHtmlSafe(oldHtmlSafe);

writer.setSerializeNulls(oldSerializeNulls);

}

}

基本的逻辑都在上面讲过了,不赘述。

到此为止 json 的序列化就基本完毕了。

四 总结

Gson 的代码封装很薄,本身不难,但是为了照顾兼容性,代码中存在很多条件判断,导致代码看上去很繁琐。同时为了兼顾性能做了很多有意思的设计,比如获取适配器的时候的双缓存设计,应该是为了提高解析器的复用效率,具体有待研究。

总结一下 Gson 的基本思路:

· 解析器(Gson)将使用者传入的字符串或对象存入读取器(Reader)或者写入器(Writer)中

· 解析器遍历并获取能够处理对应类型的适配器工厂(TypeAdapterFactory)

· 适配器工厂会创建出对应类型的适配器(TypeAdapter)

· 解析器将阅读器或写入器交给适配器

· 适配器自行通过业务逻辑操作读取器或写入器,输出需要的结果

· 解析器接收此输出,并交给使用者

五 一点唠叨

· Gson 太过强调功能的全面,解析器的初始化非常复杂

· JsonReader 的状态控制太过复杂和精密,笔者到现在也没全部弄清楚

· 在本篇源码解析中,Gson 内部还有一些拓展功能,比如 JsonElement、JsonParser 等的工具类没有提及

· 仅为个人的学习笔记,可能存在错误或者表述不清的地方,有缘补充

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值