@JsonAdapter(UserJsonAdapter.class) 自定义解析类继承TypeAdapter<> 需要重写read跟write write是把对象写成字符串,read是把字符串写成对象
几种用法: (1)调用反射的TypeAdapter 耗性能
public static void test1() {
//基本使用
//反射的TypeAdapter 耗性能
Gson gson = new GsonBuilder()
.setPrettyPrinting()
.serializeNulls().create();
Foo foo = new Foo();
String json = gson.toJson(foo);
System.out.println(json);
}
(2)自定义TypeAdapter
TypeAdapter
JsonReader
JsonWriter
Gson gson = new GsonBuilder().registerTypeAdapter(Foo.class , new TypeAdapter<Foo>() { @Override public void write(JsonWriter out, Foo value) throws IOException { if (value == null) {//进行非空判断 out.nullValue(); return; } //把Food对象制定成你自己定义的格式的字符串进行输出:不一定是json格式了,就看你怎么组织 out.beginObject(); out.name("s").value(value.s+"sdfas"); out.name("i").value(value.i); out.endObject(); } @Override public Foo read(JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) {//进行非空判断 in.nextNull(); return null; } //读取json串并封装成Foo对象返回之 final Foo foo = new Foo(); in.beginObject(); while (in.hasNext()) { switch (in.nextName()) { case "s": foo.s = in.nextString(); break; case "i": foo.i = in.nextInt(); break; } } in.endObject(); return foo; } }).create(); Foo foo = new Foo(); String json = gson.toJson(foo); System.out.println(json);
//如果不判断非空处理的话也可以.nullSafe() 系统自动帮你处理
public static void test3() { //nullSafe()演示 Gson gson = new GsonBuilder().registerTypeAdapter(Foo.class , new TypeAdapter<Foo>() { @Override public void write(JsonWriter out, Foo value) throws IOException { out.beginObject(); out.name("s").value(value.s); out.name("i").value(value.i); out.endObject(); } @Override public Foo read(JsonReader in) throws IOException { //读取json串并封装成Foo对象返回之 final Foo foo = new Foo(); in.beginObject(); while (in.hasNext()) { switch (in.nextName()) { case "s": foo.s = in.nextString(); break; case "i": foo.i = in.nextInt(); break; } } in.endObject(); return foo; } }.nullSafe()).create(); Foo foo = new Foo(); String json = gson.toJson(foo); System.out.println(json); } }
//遇到穿null数组的有两种解决办法一种是自定义TypeAdapter
public static void test2() {
//TODO:
String json = "{\n" +
" \"name\": \"java\",\n" +
" \"authors\": \"\"\n" +
"}";
Gson gson = new Gson();
GsonError1 gsonError1 = gson.fromJson(json, GsonError1.class);
System.out.println(gsonError1);
}
另一种实现JsonDeserializer 反序列化接口
static class GsonError1Deserializer implements JsonDeserializer<GsonError1> {
@Override
public GsonError1 deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
final JsonObject jsonObject = json.getAsJsonObject();
final JsonElement jsonTitle = jsonObject.get("name");
final String name = jsonTitle.getAsString();
JsonElement jsonAuthors = jsonObject.get("authors");
GsonError1 gsonError1 = new GsonError1();
if (jsonAuthors.isJsonArray()) {//如果数组类型,此种情况是我们需要的
//关于context在文章最后有简单说明
GsonError1.AuthorsBean[] authors = context.deserialize(jsonAuthors, GsonError1.AuthorsBean[].class);
gsonError1.setAuthors(Arrays.asList(authors));
} else {//此种情况为无效情况
gsonError1.setAuthors(null);
}
gsonError1.setName(name);
return gsonError1;
}
}
JsonElement
该类是一个抽象类,代表着json串的某一个元素。这个元素可以是一个Json(JsonObject)、可以是一个数组(JsonArray)、可以是一个Java的基本类型(JsonPrimitive)、当然也可以为null(JsonNull);JsonObject,JsonArray,JsonPrimitive,JsonNull都是JsonElement这个
抽象类的
{
"key": "value",
"arrays": []
}
例如这个最外层是一个JsonObject vale是一个JsonPrimitive []是一个JsonArray 每一个元素都是一个JsonElement
TypeAdapters
这个类中定义了几乎所有的基础类型的TypeAdapter和Factory,我们现在挑出一个来研究一下。这是一个URL对象的JSON转换器啦。
public static final TypeAdapter<URL> URL = new TypeAdapter<URL>() {
@Override
public URL read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
String nextString = in.nextString(); //读出in中的内容
return "null".equals(nextString) ? null : new URL(nextString);//根据读出的内容,创建URL对象
}
@Override
public void write(JsonWriter out, URL value) throws IOException {
out.value(value == null ? null : value.toExternalForm()); //写入内容
}
};
public static final TypeAdapterFactory URL_FACTORY = newFactory(URL.class, URL);//创建Facotry啦
我们可以看到,这是一个URL的转换器
也就是说一种类型对应着一种TypeAdapters
如果说这个类是没有的,要么自己自定义TypeAdapters去解析要么系统会调用反射的ReflectiveTypeAdapter去解析
TypeAdapterFactory
这是一个接口,自定义了一个函数:<T> TypeAdapter<T> create(Gson gson, TypeToken<T> type);
,具体的实现方法,每一个TypeAdapter都由它生产出来
TypeToken
获取gson泛型解析T的类型
Gson流程图
newGnos的时候的参数
Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingPolicy, final Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls, boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe, boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues, LongSerializationPolicy longSerializationPolicy, List<TypeAdapterFactory> typeAdapterFactories) { this.constructorConstructor = new ConstructorConstructor(instanceCreators);//实例构造器 this.serializeNulls = serializeNulls;//序列化空 this.generateNonExecutableJson = generateNonExecutableGson;//生成不可执行前缀(用来防止攻击) this.htmlSafe = htmlSafe;//html转义 this.prettyPrinting = prettyPrinting;//缩进打印 this.lenient = lenient;//宽松的容错性 //TypeAdapte的工厂列表 最先添加的优先级更高 List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>(); //以下都是往工厂列表加入TypeAdapterFactory //构建不能被重载的TypeAdapter // 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); //用户自定义的TypeAdapter工厂 // user's type adapters factories.addAll(typeAdapterFactories); //以下为默认的TypeAdapter // 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); //复合的TypeAdapter // type adapters for composite and user-defined types 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(//最后添加反射机制用的factory constructorConstructor, fieldNamingPolicy, excluder)); this.factories = Collections.unmodifiableList(factories); }
excluder 排除器 处理一些不需要序列化的东西 @Expose 注解等
public final class Excluder implements TypeAdapterFactory, Cloneable { private static final double IGNORE_VERSIONS = -1.0d; public static final Excluder DEFAULT = new Excluder(); private double version = IGNORE_VERSIONS; private int modifiers = Modifier.TRANSIENT | Modifier.STATIC; private boolean serializeInnerClasses = true; private boolean requireExpose; private List<ExclusionStrategy> serializationStrategies = Collections.emptyList(); private List<ExclusionStrategy> deserializationStrategies = Collections.emptyList(); @Override protected Excluder clone() { try { return (Excluder) super.clone(); } catch (CloneNotSupportedException e) { throw new AssertionError(e); } } public Excluder withVersion(double ignoreVersionsAfter) { Excluder result = clone(); result.version = ignoreVersionsAfter; return result; } public Excluder withModifiers(int... modifiers) { //static transient 也不会序列化 Excluder result = clone(); result.modifiers = 0; for (int modifier : modifiers) { result.modifiers |= modifier; } return result; }
.......
@Expose
private String firstName;//参与序列化(JAVA对象转为JSON)/反序列化(JSON转为JAVA对象)
@Expose(serialize = false)
private String lastName;//参与反序列化
@Expose(serialize = false, deserialize = true)
private String emailAddress; //不参与
private String password;//不参与
@Since(1.0) private String emailAddress; //当前版本>=1.0时才会参与序列化/反序列化,否则忽略 @Since(1.1) private String password;//当前版本>=1.0时才会参与序列化/反序列化,否则忽略
@Until(1.1) private String emailAddress;//当前版本<=1.1时参加序列化/反序列化 @Until(1.1) private String password;//当前版本<=1.1时参加序列化/反序列化
FieldNamingStrategy 字段命名策略 处理这些
@SerializedName("name") //a => name key为name String a; @SerializedName(value = "name1", alternate = {"name2", "name3"}) //第一个
String b;
ConstructorConstructor 构造器 (用到反射的TypeAdapter才需要使用构造器,使用自定义的不需要,因为类可以直接new出来)
public final class ConstructorConstructor { private final Map<Type, InstanceCreator<?>> instanceCreators; public ConstructorConstructor(Map<Type, InstanceCreator<?>> instanceCreators) { this.instanceCreators = instanceCreators; } //通过实例返回一个构造器 public <T> ObjectConstructor<T> get(TypeToken<T> typeToken) { final Type type = typeToken.getType(); final Class<? super T> rawType = typeToken.getRawType(); // first try an instance creator //首先从集合中取看有没有相同的Type,有就创造实例并返回 @SuppressWarnings("unchecked") // types must agree final InstanceCreator<T> typeCreator = (InstanceCreator<T>) instanceCreators.get(type); if (typeCreator != null) { return new ObjectConstructor<T>() { @Override public T construct() { return typeCreator.createInstance(type); } }; } //然后根据原始类型取,去集合中取 // Next try raw type match for instance creators @SuppressWarnings("unchecked") // types must agree final InstanceCreator<T> rawTypeCreator = (InstanceCreator<T>) instanceCreators.get(rawType); if (rawTypeCreator != null) { return new ObjectConstructor<T>() { @Override public T construct() { return rawTypeCreator.createInstance(type); } }; }
........
顺序
jsonstr --->排除器--->自定义TypeAdapter --->gson自带的TypeAdapter--->反射 RefctiveTypeAdapter
调用toJson方法
toJson
gson.toJson();
public String toJson(Object src) { if (src == null) { return toJson(JsonNull.INSTANCE); } return toJson(src, src.getClass()); }
public String toJson(JsonElement jsonElement) { StringWriter writer = new StringWriter(); toJson(jsonElement, writer); return writer.toString(); }
最终调用这个方法通过
public void toJson(JsonElement jsonElement, JsonWriter writer) throws JsonIOException { boolean oldLenient = writer.isLenient(); writer.setLenient(true); boolean oldHtmlSafe = writer.isHtmlSafe(); writer.setHtmlSafe(htmlSafe); boolean oldSerializeNulls = writer.getSerializeNulls(); writer.setSerializeNulls(serializeNulls); try { Streams.write(jsonElement, writer);//实际上是TypeAdapter } catch (IOException e) { throw new JsonIOException(e); } finally { writer.setLenient(oldLenient); writer.setHtmlSafe(oldHtmlSafe); writer.setSerializeNulls(oldSerializeNulls); } }
JsonWriter里面比较重要的方法
/** * Encodes {@code value}. * * @param value the literal string value, or null to encode a null literal. * @return this writer. */ 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; }
//字符串的操作
private void string(String value) throws IOException { String[] replacements = htmlSafe ? HTML_SAFE_REPLACEMENT_CHARS : REPLACEMENT_CHARS; out.write('\"'); int last = 0; int length = value.length(); for (int i = 0; i < length; i++) { char c = value.charAt(i); String replacement; if (c < 128) { replacement = replacements[c]; if (replacement == null) { continue; } } else if (c == '\u2028') { replacement = "\\u2028"; } else if (c == '\u2029') { replacement = "\\u2029"; } else { continue; } if (last < i) { out.write(value, last, i - last); } out.write(replacement); last = i + 1; } if (last < length) { out.write(value, last, length - last); } out.write('\"'); } private void newline() throws IOException { if (indent == null) { return; } out.write('\n'); for (int i = 1, size = stackSize; i < size; i++) { out.write(indent); } }
JsonReader doPeek
fromJson
public <T> 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<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT); //根据TypeToken获取相应的能够处理的TypeAdapter TypeAdapter<T> typeAdapter = getAdapter(typeToken); //反射创建object 都没有换取都合适的就会用到反射 T object = typeAdapter.read(reader); return object; } catch (EOFException e) { /* * For compatibility with JSON 1.5 and earlier, we return null for empty * documents instead of throwing. */ if (isEmpty) { return null; } throw new JsonSyntaxException(e); } catch (IllegalStateException e) { throw new JsonSyntaxException(e); } catch (IOException e) { // TODO(inder): Figure out whether it is indeed right to rethrow this as JsonSyntaxException 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); } }
//获取对应的适配器
public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) { //typeTokenCache 是Gson中的一个map对象,用于存储TypeAdapter //typeTokenCache是一个Gson中各个线程共用的一个缓存池 TypeAdapter<?> cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type); if (cached != null) { //如果本身就有存储了,就直接返回 return (TypeAdapter<T>) cached; } //calls是一个TreadLocal对象 //TreadLocal是Gson中单个线程使用的缓存池,在里面存入的对象会在finally代码块中清空掉 Map<TypeToken<?>, FutureTypeAdapter<?>> threadCalls = calls.get(); //判断是否需要清空TreadLocal boolean requiresThreadLocalCleanup = false; if (threadCalls == null) { threadCalls = new HashMap<TypeToken<?>, FutureTypeAdapter<?>>(); calls.set(threadCalls); //这里存入了对象,所以需要清空TreadLocal requiresThreadLocalCleanup = true; } //如果存在对象,就会在这里取出来并返回 //FutureTypeAdapter是一个门面模式的应用,其实本质是使用内部的TypeAdapter去处理业务 //如果内部没有存入实际处理业务的TypeAdapter,就会报错 // the key and value type parameters always agree FutureTypeAdapter<T> ongoingCall = (FutureTypeAdapter<T>) threadCalls.get(type); if (ongoingCall != null) { return ongoingCall; } try { FutureTypeAdapter<T> call = new FutureTypeAdapter<T>(); threadCalls.put(type, call); //这个方法的主体是这个for循环,用于从Gson初始化的时候储存的列表中获取到对应的TypeAdapter for (TypeAdapterFactory factory : factories) { //TypeAdapter的create(...)方法用于对于不是对应类型的参数会返回null TypeAdapter<T> 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(); } } }
peek方法分析
public JsonToken peek() throws IOException { int p = peeked; if (p == PEEKED_NONE) { p = doPeek(); } switch (p) { case PEEKED_BEGIN_OBJECT: return JsonToken.BEGIN_OBJECT; case PEEKED_END_OBJECT: return JsonToken.END_OBJECT; case PEEKED_BEGIN_ARRAY: return JsonToken.BEGIN_ARRAY; case PEEKED_END_ARRAY: return JsonToken.END_ARRAY; case PEEKED_SINGLE_QUOTED_NAME: case PEEKED_DOUBLE_QUOTED_NAME: case PEEKED_UNQUOTED_NAME: return JsonToken.NAME; case PEEKED_TRUE: case PEEKED_FALSE: return JsonToken.BOOLEAN; case PEEKED_NULL: return JsonToken.NULL; case PEEKED_SINGLE_QUOTED: case PEEKED_DOUBLE_QUOTED: case PEEKED_UNQUOTED: case PEEKED_BUFFERED: return JsonToken.STRING; case PEEKED_LONG: case PEEKED_NUMBER: return JsonToken.NUMBER; case PEEKED_EOF: return JsonToken.END_DOCUMENT; default: throw new AssertionError(); } }
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]; if (peekStack == JsonScope.EMPTY_ARRAY) { stack[stackSize - 1] = JsonScope.NONEMPTY_ARRAY; } else if (peekStack == JsonScope.NONEMPTY_ARRAY) { //在第一次调用nextNonWhitespace(true)方法的时候,json字符串会被转换存为一个char数组 //该方法以int值的形式返回下一个要解析的char对象 // Look for a comma before the next element. int c = nextNonWhitespace(true); switch (c) { //peeked是JsonReader中最重要的用来状态控制的int变量 //peeked喝stack会协同控制JsonReader的逻辑行为 case ']': return peeked = PEEKED_END_ARRAY;//PEEKED_END_ARRAY = 4 case ';': //检查标准协议选项,json标准中的符号没有分号 //所以在lenient = false的时候就会报错 checkLenient(); // fall-through case ',': break; default: throw syntaxError("Unterminated array"); } } else if (peekStack == JsonScope.EMPTY_OBJECT || peekStack == JsonScope.NONEMPTY_OBJECT) { stack[stackSize - 1] = JsonScope.DANGLING_NAME; // Look for a comma before the next element. if (peekStack == JsonScope.NONEMPTY_OBJECT) { int c = nextNonWhitespace(true); switch (c) { case '}': return peeked = PEEKED_END_OBJECT; case ';': checkLenient(); // fall-through case ',': break; default: throw syntaxError("Unterminated object"); } } int c = nextNonWhitespace(true); switch (c) { case '"': return peeked = PEEKED_DOUBLE_QUOTED_NAME; case '\'': checkLenient(); return peeked = PEEKED_SINGLE_QUOTED_NAME; case '}': if (peekStack != JsonScope.NONEMPTY_OBJECT) { return peeked = PEEKED_END_OBJECT; } else { throw syntaxError("Expected name"); } default: checkLenient(); pos--; // Don't consume the first character in an unquoted string. if (isLiteral((char) c)) { return peeked = PEEKED_UNQUOTED_NAME; } else { throw syntaxError("Expected name"); } } } else if (peekStack == JsonScope.DANGLING_NAME) { stack[stackSize - 1] = JsonScope.NONEMPTY_OBJECT; // Look for a colon before the value. int c = nextNonWhitespace(true); switch (c) { case ':': break; case '=': checkLenient(); if ((pos < limit || fillBuffer(1)) && buffer[pos] == '>') { pos++; } break; default: throw syntaxError("Expected ':'"); } } else if (peekStack == JsonScope.EMPTY_DOCUMENT) { if (lenient) { consumeNonExecutePrefix(); } 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--; } } else if (peekStack == JsonScope.CLOSED) { throw new IllegalStateException("JsonReader is closed"); } int c = nextNonWhitespace(true); switch (c) { case ']': if (peekStack == JsonScope.EMPTY_ARRAY) { return peeked = PEEKED_END_ARRAY; } // fall-through to handle ",]" case ';': case ',': // In lenient mode, a 0-length literal in an array means 'null'. 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--; // Don't consume the first character in a literal value. } int result = peekKeyword(); if (result != PEEKED_NONE) { return result; } result = peekNumber(); if (result != PEEKED_NONE) { return result; } if (!isLiteral(buffer[pos])) { throw syntaxError("Expected value"); } checkLenient(); return peeked = PEEKED_UNQUOTED; }
//解析字符串
private int nextNonWhitespace(boolean throwOnEof) throws IOException { /* * This code uses ugly local variables 'p' and 'l' representing the 'pos' * and 'limit' fields respectively. Using locals rather than fields saves * a few field reads for each whitespace character in a pretty-printed * document, resulting in a 5% speedup. We need to flush 'p' to its field * before any (potentially indirect) call to fillBuffer() and reread both * 'p' and 'l' after any (potentially indirect) call to the same method. */ char[] buffer = this.buffer; int p = pos; int l = limit; while (true) { if (p == l) { pos = p; if (!fillBuffer(1)) { break; } p = pos; l = limit; } int c = buffer[p++]; if (c == '\n') { lineNumber++; lineStart = p; continue; } else if (c == ' ' || c == '\r' || c == '\t') { continue; } if (c == '/') { pos = p; if (p == l) { pos--; // push back '/' so it's still in the buffer when this method returns boolean charsLoaded = fillBuffer(2); pos++; // consume the '/' again if (!charsLoaded) { return c; } } checkLenient(); char peek = buffer[pos]; switch (peek) { case '*': // skip a /* c-style comment */ pos++; if (!skipTo("*/")) { throw syntaxError("Unterminated comment"); } p = pos + 2; l = limit; continue; case '/': // skip a // end-of-line comment pos++; skipToEndOfLine(); p = pos; l = limit; continue; default: return c; } } else if (c == '#') { pos = p; /* * Skip a # hash end-of-line comment. The JSON RFC doesn't * specify this behaviour, but it's required to parse * existing documents. See http://b/2571423. */ checkLenient(); skipToEndOfLine(); p = pos; l = limit; } else { pos = p; return c; } } if (throwOnEof) { throw new EOFException("End of input" + locationString()); } else { return -1; } }
直接ReflectiveTypeAdapterFactory反射分析流程
@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! } ObjectConstructor<T> constructor = constructorConstructor.get(type);//首先根据类型获取到构造器 return new Adapter<T>(constructor, getBoundFields(gson, type, raw)); }
TypeToken//相当于拿到一个类下面所有的变量字段
//这个方法用于把bean类的字段搜集
private Map<String, BoundField> getBoundFields(Gson context, TypeToken<?> type, Class<?> raw) { Map<String, BoundField> result = new LinkedHashMap<String, BoundField>();//创建一个Map结构,存放所有的BoundField if (raw.isInterface()) { return result; } Type declaredType = type.getType(); while (raw != Object.class) {//如果类型是Object则结束循环 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);//获取该Filed的名字(Gson通过注解可以给一个属性) 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 //创建BoundField //根据filed,type,以及是否支持序列化和反序列化来创建一个BoundField对象 BoundField boundField = createBoundField(context, field, name, TypeToken.get(fieldType), serialize, deserialize); //讲BoundField放入Map中,获取将替换的value(如果有的话) //讲属性名称作为key,boundField作为vale保存到result中 BoundField replaced = result.put(name, boundField); //如果之前解析过对应的这个值的话,这里就会导致previous不为空,从而报错 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; }
private ReflectiveTypeAdapterFactory.BoundField createBoundField( final Gson context, final Field field, final String name, final TypeToken<?> fieldType, boolean serialize, boolean deserialize) { //是否是原始数据类型(int,boolean,float..) final boolean isPrimitive = Primitives.isPrimitive(fieldType.getRawType()); // special casing primitives here saves ~5% on Android... JsonAdapter annotation = field.getAnnotation(JsonAdapter.class); TypeAdapter<?> mapped = null; if (annotation != null) { //Gson尝试获取该类型的TypeAdapter mapped = jsonAdapterFactory.getTypeAdapter( constructorConstructor, context, fieldType, annotation); } final boolean jsonAdapterPresent = mapped != null; //获取当前json串的一个name/value对应JavaBean里面的变量类型type,或者这个type对应的TypeAdapter类 if (mapped == null) mapped = context.getAdapter(fieldType);//获取对应的基本类型 //final变量,便于内部类使用 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); } //ReflectiveTypeAdapter委托的Json读操作会调用到这里 @Override void read(JsonReader reader, Object value) throws IOException, IllegalAccessException {、 //通过该属性的类型对应的TypeAdapter尝试读取json串 //如果是基础类型,则直接读取, //如果是复合类型则递归之前的流程 Object fieldValue = typeAdapter.read(reader);//获取下一个jsontoken而不消耗它 if (fieldValue != null || !isPrimitive) { field.set(value, fieldValue);//更新filed值 } } @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 } }; }
return new Adapter<T>(constructor, getBoundFields(gson, type, raw));new Adapte的时候调用read方法
Adapter(ObjectConstructor<T> constructor, Map<String, BoundField> boundFields) { this.constructor = constructor; this.boundFields = boundFields; } @Override public T read(JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull(); return null; } T instance = constructor.construct(); try { in.beginObject(); while (in.hasNext()) { String name = in.nextName();.//开始逐个读取json串中的key BoundField field = boundFields.get(name);//通过key寻找对应的属性 if (field == null || !field.deserialized) { in.skipValue(); } else { field.read(in, instance); } } } catch (IllegalStateException e) { throw new JsonSyntaxException(e); } catch (IllegalAccessException e) { throw new AssertionError(e); } in.endObject(); return instance; }
@Override void read(JsonReader reader, Object value)//ReflectiveTypeAdapter中上面使用到的 throws IOException, IllegalAccessException { Object fieldValue = typeAdapter.read(reader); if (fieldValue != null || !isPrimitive) { field.set(value, fieldValue); } }