1.将一个json 字符串转换为 Java 集合的例子
public class GsonDeserializer {
static class AuthorsBean{
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "AuthorsBean{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
'}';
}
}
public static void main(String[] args) {
String json = "[\n" +
" {\n" +
" \"id\": \"1'\",\n" +
" \"name\": \"Joshua Bloch'\"\n" +
" },\n" +
" {\n" +
" \"id\": \"2'\",\n" +
" \"name\": \"Tom\"\n" +
" }\n" +
" ]";
Gson gson=new Gson();
Type type=new TypeToken<ArrayList<AuthorsBean>>(){}.getType();
ArrayList<AuthorsBean> mGsonDeserializer = gson.fromJson(json, type);
System.out.println(mGsonDeserializer.toString());
}
}
- 打印信息
[AuthorsBean{id='1'', name='Joshua Bloch''}, AuthorsBean{id='2'', name='Tom'}]
2.上面的实例代码就是我们常常做的类似从服务器获取json数据后转换为Java 数组情形,那么Gson到底做了什么操作了?
public Gson() {
this(Excluder.DEFAULT, FieldNamingPolicy.IDENTITY,
Collections.<Type, InstanceCreator<?>>emptyMap(), DEFAULT_SERIALIZE_NULLS,
DEFAULT_COMPLEX_MAP_KEYS, DEFAULT_JSON_NON_EXECUTABLE, DEFAULT_ESCAPE_HTML,
DEFAULT_PRETTY_PRINT, DEFAULT_LENIENT, DEFAULT_SPECIALIZE_FLOAT_VALUES,
LongSerializationPolicy.DEFAULT, null, DateFormat.DEFAULT, DateFormat.DEFAULT,
Collections.<TypeAdapterFactory>emptyList(), Collections.<TypeAdapterFactory>emptyList(),
Collections.<TypeAdapterFactory>emptyList());
}
Gson(Excluder excluder, FieldNamingStrategy fieldNamingStrategy,
Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls,
boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,
LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle,
int timeStyle, List<TypeAdapterFactory> builderFactories,
List<TypeAdapterFactory> builderHierarchyFactories,
List<TypeAdapterFactory> factoriesToBeAdded) {
this.excluder = excluder;//排除器
this.fieldNamingStrategy = fieldNamingStrategy;//字段命名策略
this.instanceCreators = instanceCreators;
this.constructorConstructor = new ConstructorConstructor(instanceCreators);//实例构造器
this.serializeNulls = serializeNulls;//序列化空
this.complexMapKeySerialization = complexMapKeySerialization;
this.generateNonExecutableJson = generateNonExecutableGson;//生成不可执行前缀(用来防止
this.htmlSafe = htmlSafe;//html转义
this.prettyPrinting = prettyPrinting;//缩进打印
this.lenient = lenient;//宽松的容错性
this.serializeSpecialFloatingPointValues = serializeSpecialFloatingPointValues;
this.longSerializationPolicy = longSerializationPolicy;
this.datePattern = datePattern;
this.dateStyle = dateStyle;
this.timeStyle = timeStyle;
this.builderFactories = builderFactories;
this.builderHierarchyFactories = builderHierarchyFactories;
//TypeAdapter的工厂列表
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);
// 排除器必须在所有的用于自定义的typeAdapter之前
// the excluder must precede all adapters that handle user-defined types
factories.add(excluder);
//用户自定义的typeAdapter工厂
// users' type adapters
factories.addAll(factoriesToBeAdded);
//以下为默认的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));
this.jsonAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor);
factories.add(jsonAdapterFactory);
factories.add(TypeAdapters.ENUM_FACTORY);
factories.add(new ReflectiveTypeAdapterFactory(//最后添加反射机制用的factory
constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory));
this.factories = Collections.unmodifiableList(factories);
}
1.首先我们看Gson的构造函数,在构造函数中添加了很多对应数据类型的TypeAdapterFactory,而每一个TypeAdapterFactory都对应有一个TypeAdapter,而TypeAdapter就是用来对对应类型的数据进行序列化/反序列操作
public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException {
//将字符串转成 object 的主体方法
Object object = fromJson(json, (Type) classOfT);
Log.i("Primitives","wrap:"+Primitives.wrap(classOfT)+"--》"+Primitives.wrap(classOfT).cast(object));
//cast:将对象强制转换为由参数对象表示的类或接口。
return Primitives.wrap(classOfT).cast(object);
}
2. fromJson是反序列化的入口,传递的参数第一个是Json字符串,第二个是需要将json字符串转换为Java bean的class对象,该方法会调用fromJson重载,将json字符串以及class对象对应的type传递过去,返回的就是Object对象,调用Primitives.wrap(classOfT).cast(object)对返回的结果进行进一步的检测,若没有问题就会转换为参数对象
public <T> 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;
}
3.该方法会判断json字符串是否是空的,若是的直接返回空,不再继续后续的操作;若不为空,则创建一个StringReader,用来读取json字符串中内容,最后调用fromJosn的重载方法,将type和stringReader传递进去
public <T> 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;
}
public JsonReader newJsonReader(Reader reader) {
JsonReader jsonReader = new JsonReader(reader);
jsonReader.setLenient(lenient);
return jsonReader;
}
/**
* 判断对象是否为空 且文档标记是否是否是END_DOCUMENT
* @param obj
* @param reader
*/
private static void assertFullConsumption(Object obj, JsonReader reader) {
try {
if (obj != null && reader.peek() != JsonToken.END_DOCUMENT) {
//json文档没有被完全使用
throw new JsonIOException("JSON document was not fully consumed.");
}
} catch (MalformedJsonException e) {
throw new JsonSyntaxException(e);
} catch (IOException e) {
throw new JsonIOException(e);
}
}
4.构建JsonReader将StringReader包装进去,然后继续调用fromJson()重载方法 ,将JsonReader和type传递进行反序列化操作并返回结果,获取到结果后会调用assertFullConsumption()根据状态检测json是否已经完全被解析出来了,若状态有问题,表示json还没有被完全解析出来,将会抛异常
//Gson类中代码
public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
boolean isEmpty = true;
boolean oldLenient = reader.isLenient();
Log.i("fromJson","oldLenient:"+oldLenient);
//打开 reader 的标准化检验
reader.setLenient(true) ;
try {
//此处相当于调用了一次 JsonReader 中的 doPeek() 方法
Log.i("fromJson","----------------------------------");
reader.peek();
Log.i("fromJson","----------------------------------");
isEmpty = false;
//TypeToken 本质上是 Class 的增强封装类 将typeOfT封装到TypeToken中 以便于获取typeOfT的类型
TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);
Log.i("fromJson","typeToken:"+typeToken);
//根据 TypeToken 获取对应的能够处理其类型的 TypeAdapter
TypeAdapter<T> typeAdapter = getAdapter(typeToken);
Log.i("fromJson","typeAdapter:"+typeAdapter);
//反射创建 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);
}
}
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 是一个 ThreadLocal 对象
//ThreadLocal 是 Gson 中单个线程使用的缓存池,在里面存入的对象会在 finally 代码块中清空掉
Map<TypeToken<?>, FutureTypeAdapter<?>> threadCalls = calls.get();
//判断是否需要清空 ThreadLocal
boolean requiresThreadLocalCleanup = false;
if (threadCalls == null) {
threadCalls = new HashMap<TypeToken<?>, FutureTypeAdapter<?>>();
calls.set(threadCalls);
//这里存入了对象,所以需要清空 ThreadLocal
requiresThreadLocalCleanup = true;
}
//如果存在对象,就会在这里取用出来并返回
//FutureTypeAdapter 是一个门面模式的应用,其实本质是使用内部的 TypeAdapter 去处理业务
//如果内部没有存入实际处理业务的 TypeAdapter,就会报错
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
// Log.i("TypeAdapterFactory","TypeAdapterFactory:"+factory);
TypeAdapter<T> candidate = factory.create(this, type);
if (candidate != null) {
//在此处会存入业务处理的 TypeAdapter
call.setDelegate(candidate);
//在此处存入公用缓存
typeTokenCache.put(type, candidate);
Log.i(TAG,"采用的factory1111:"+factory+"-->"+candidate);
return candidate;
}
}
throw new IllegalArgumentException("GSON (" + GsonBuildConfig.VERSION + ") cannot handle " + type);
} finally {
//清除 ThreadLocal 缓存
threadCalls.remove(type);
if (requiresThreadLocalCleanup) {
calls.remove();
}
}
}
//JsonReader中的方法
public JsonToken peek() throws IOException {
int p = peeked;
Log.i("fromJson","peek:"+p);
if (p == PEEKED_NONE) {
p = doPeek();
Log.i("fromJson","peek doPeek:"+p);
}
switch (p) {
case PEEKED_BEGIN_OBJECT://文档开始
Log.i("fromJson","peek:PEEKED_BEGIN_OBJECT");
return JsonToken.BEGIN_OBJECT;
case PEEKED_END_OBJECT:
Log.i("fromJson","peek:PEEKED_BEGIN_OBJECT");
return JsonToken.END_OBJECT;
case PEEKED_BEGIN_ARRAY:
Log.i("fromJson","peek:PEEKED_BEGIN_ARRAY");
return JsonToken.BEGIN_ARRAY;
case PEEKED_END_ARRAY:
Log.i("fromJson","peek:PEEKED_END_ARRAY");
return JsonToken.END_ARRAY;
case PEEKED_SINGLE_QUOTED_NAME:
case PEEKED_DOUBLE_QUOTED_NAME:
case PEEKED_UNQUOTED_NAME:
Log.i("fromJson","peek:PEEKED_SINGLE_QUOTED_NAME");
return JsonToken.NAME;
case PEEKED_TRUE:
case PEEKED_FALSE:
Log.i("fromJson","peek:PEEKED_TRUE");
return JsonToken.BOOLEAN;
case PEEKED_NULL:
Log.i("fromJson","peek:PEEKED_NULL");
return JsonToken.NULL;
case PEEKED_SINGLE_QUOTED:
case PEEKED_DOUBLE_QUOTED:
case PEEKED_UNQUOTED:
case PEEKED_BUFFERED:
Log.i("fromJson","peek:PEEKED_SINGLE_QUOTED");
return JsonToken.STRING;
case PEEKED_LONG:
case PEEKED_NUMBER:
Log.i("fromJson","peek:PEEKED_LONG");
return JsonToken.NUMBER;
case PEEKED_EOF:
Log.i("fromJson","peek:PEEKED_EOF");
return JsonToken.END_DOCUMENT;
default:
throw new AssertionError();
}
/**
* Returns the string up to but not including {@code quote}, unescaping any
* character escape sequences encountered along the way. The opening quote
* should have already been read. This consumes the closing quote, but does
* not include it in the returned string.
*
* @param quote either ' or ".
* @throws NumberFormatException if any unicode escape sequences are
* malformed.
*/
private String nextQuotedValue(char quote) throws IOException {
// Like nextNonWhitespace, this uses locals 'p' and 'l' to save inner-loop field access.
char[] buffer = this.buffer;
Log.i("nextName","----------------------quote:"+pos+"--》"+limit+"-->"+"-->"+buffer.length+" "+new String(buffer));
for (int i=0;i<limit;i++){
Log.i("nextName","一个一个的char字符:"+i+" "+new String(new char[]{buffer[i]}));
}
//{
// "name":"v1",
// "name1":"v2",
// "c":"V3"
// }
StringBuilder builder = null;
while (true) {
int p = pos;
int l = limit;
/* the index of the first character n ot yet appended to the builder. */
int start = p;
Log.i("nextName","buffer while循环 "+start+" "+pos+"-->"+p+"-->"+l+"---"+(p - start - 1));
while (p < l) {
int c = buffer[p++];
Log.i("nextName","buffer 循环之中: "+start+" "+" "+p+" "+pos+"--》"+c+"-->"+quote);
if (c == quote) {//从第一个"开始 查找下一个" 然后截取中间一段 就是key
Log.i("nextName","buffer 赋值之前: "+start+" "+" "+p+" "+pos);
pos = p;
Log.i("nextName","buffer 赋值之后: "+start+" "+" "+p+" "+pos);
int len = p - start - 1;
if (builder == null) {
String str=new String(buffer, start, len);
Log.i("nextName","buffer builder == null: "+start+" "+len+" "+pos+" "+str);
return str;
} else {
builder.append(buffer, start, len);
Log.i("nextName","buffer builder.append: "+builder.toString());
return builder.toString();
}
} else if (c == '\\') {
pos = p;
int len = p - start - 1;
if (builder == null) {
int estimatedLength = (len + 1) * 2;
builder = new StringBuilder(Math.max(estimatedLength, 16));
}
builder.append(buffer, start, len);
builder.append(readEscapeCharacter());
Log.i("nextName","buffer \\: "+builder.toString());
p = pos;
l = limit;
start = p;
} else if (c == '\n') {
lineNumber++;
lineStart = p;
Log.i("nextName","buffer \n: "+builder.toString());
}
}
if (builder == null) {
int estimatedLength = (p - start) * 2;
builder = new StringBuilder(Math.max(estimatedLength, 16));
}
builder.append(buffer, start, p - start);
pos = p;
Log.i("nextName","buffer haha: "+builder.toString());
Log.i("nextName","----------------------quotequote");
if (!fillBuffer(1)) {
throw syntaxError("Unterminated string");
}
}
}
}
- 1.该方法首先会调用 jsonReader.peek()进行状态修改。默认peek的状态为PEEKED_NONE,而stack是一个32位的数组,用于存储当前json解析的状态的,它默认第一个位置的状态值为JsonScope.EMPTY_DOCUMENT(当前位于空文档状态)
- 2.在peek()方法中,第一次会调用doPeek()方法,在doPeek()中发现当前stack第一个位置的状态EMPTY_DOCUMENT,那么就会进行状态修改,将stack第一个位置的状态由EMPTY_DOCUMENT变更为JsonScope.NONEMPTY_DOCUMENT,p的状态值被修改为PEEKED_BEGIN_ARRAY
- 3.当状态被修改后,调用getAdapter()获取当前对应的TypeAdapter,之后调用typeAdapter.read(reader)开始反序列化操作
- 4.对于原始数据类型都可以从TypeAdapters中获取,若客户端通过JsonAdapter注解自定义TypeAdapter,那么将使用自定义的TypeAdapter。因此当客户端想转换为自定义Java Object的类型而又没有自己定义TypeAdapter,那么将会使用ReflectiveTypeAdapterFactory的typeAdapter,若当客户端想转换为自定义Java Array的类型而又没有自己定义TypeAdapter,那么将会使用CollectionTypeAdapterFactory的typeAdapter。当前我们是想把json字符串转换为Java bean,所以我们先看CollectionTypeAdapterFactory中read操作
public final class CollectionTypeAdapterFactory implements TypeAdapterFactory {
private final ConstructorConstructor constructorConstructor;
public CollectionTypeAdapterFactory(ConstructorConstructor constructorConstructor) {
this.constructorConstructor = constructorConstructor;
}
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Type type = typeToken.getType();
Class<? super T> rawType = typeToken.getRawType();
if (!Collection.class.isAssignableFrom(rawType)) {
return null;
}
Type elementType = $Gson$Types.getCollectionElementType(type, rawType);
TypeAdapter<?> elementTypeAdapter = gson.getAdapter(TypeToken.get(elementType));
ObjectConstructor<T> constructor = constructorConstructor.get(typeToken);
Log.i("CollectionTypeAdapter",typeToken+"-->"+elementType+"-->"+elementTypeAdapter+"-->"+constructor);
@SuppressWarnings({"unchecked", "rawtypes"}) // create() doesn't define a type parameter
TypeAdapter<T> result = new Adapter(gson, elementType, elementTypeAdapter, constructor);
return result;
}
private static final class Adapter<E> extends TypeAdapter<Collection<E>> {
private final TypeAdapter<E> elementTypeAdapter;
private final ObjectConstructor<? extends Collection<E>> constructor;
public Adapter(Gson context, Type elementType,
TypeAdapter<E> elementTypeAdapter,
ObjectConstructor<? extends Collection<E>> constructor) {
this.elementTypeAdapter =
new TypeAdapterRuntimeTypeWrapper<E>(context, elementTypeAdapter, elementType);
this.constructor = constructor;
}
@Override public Collection<E> read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
Collection<E> collection = constructor.construct();
in.beginArray();
while (in.hasNext()) {
E instance = elementTypeAdapter.read(in);
collection.add(instance);
}
in.endArray();
return collection;
}
@Override public void write(JsonWriter out, Collection<E> collection) throws IOException {
if (collection == null) {
out.nullValue();
return;
}
out.beginArray();
for (E element : collection) {
elementTypeAdapter.write(out, element);
}
out.endArray();
}
}
}
说明
- 1.当json字符串通过反序列化转换为集合时,除非客户端自定义了对应的typeAdapter,否则的话在Gson中调用getAdapter()获取到的typeAdapter()是CollectionTypeAdapterFactory
- 2.ConstructorConstructor:构造器工具,它主要用于在反序列化过程中(read)创建集合中的元素对象,将从json字符串中获取的值通过反射设置进去
- 3.create():获取集合中的元素的类型,然后调用gson的getAdapter()获取元素使用何种typeAdapter,若元素时String/Boolean/Int等类型,将会采用TypeAdapters中的对应的对应的TypeAdapter;若对于元素定义了typeadapter,那么将使用自定义的TypeAdapter; 用于元素是Java Object,且没有自定义typeAdapter,那么将采用ReflectiveTypeAdapterFactory的TypeAdapter,最后创建TypeAdapter对象
- 4.CollectionTypeAdapterFactory的writer()方式就是用于序列化操作的
- 5.CollectionTypeAdapterFactory的read()方式就是用于反序列化操作的
read()执行流程
1.首先会通过constructor.construct()构建集合对象
2.调用jsonReader.beginArray()表示文档读取开始,在beginArray()方法中因为peeked的状态为PEEKED_BEGIN_ARRAY,所以将会stackSize位置状态改为PEEKED_BEGIN_ARRAY(stack数组的第二个位置的值),peeked的状态值修改PEEKED_NONE
3.while循环in.hasNext()根据peeked的状态判断是否是PEEKED_END_OBJECT或者PEEKED_END_ARRAY,则表示json解析结束 返回false;反之,表示解析还没有完成,返回true
4.当hasNaxt()返回true,则调用elementTypeAdapter.read(in)读取一个个元素,因为元素时Java Object的,所以elementTypeAdapter是ReflectiveTypeAdapterFactory的typeadapter,读取到元素数据后添加到集合中。那么ReflectiveTypeAdapterFactory的read做了什么操作,会在后面介绍
5.当hasNext()返回false,表示整个json文档读取完成,调用 in.endArray()表示反序列化结束。
6.最后将集合返回出去
接下来我们看看集合中的元素时如何使用ReflectiveTypeAdapterFactory的typeAdapter从Json字符串中读取数据
public final class ReflectiveTypeAdapterFactory implements TypeAdapterFactory {
private static String TAG="ReflectiveTypeAdapterFactory";
private final ConstructorConstructor constructorConstructor;
private final FieldNamingStrategy fieldNamingPolicy;
private final Excluder excluder;
private final JsonAdapterAnnotationTypeAdapterFactory jsonAdapterFactory;
private final ReflectionAccessor accessor = ReflectionAccessor.getInstance();
/**
* 反射typeAdapterFactory 构造函数 在gson构造函数中被调用
* @param constructorConstructor 构造器 用于创建java bean对象 用于read中
* @param fieldNamingPolicy 命名规则
* @param excluder 过滤器
* @param jsonAdapterFactory jsonAdapter操作工厂
*/
public ReflectiveTypeAdapterFactory(ConstructorConstructor constructorConstructor,
FieldNamingStrategy fieldNamingPolicy, Excluder excluder,
JsonAdapterAnnotationTypeAdapterFactory jsonAdapterFactory) {
this.constructorConstructor = constructorConstructor;
this.fieldNamingPolicy = fieldNamingPolicy;
this.excluder = excluder;
this.jsonAdapterFactory = jsonAdapterFactory;
Log.i(TAG,"构造函数:constructorConstructor:"+constructorConstructor);
Log.i(TAG,"构造函数:fieldNamingPolicy:"+fieldNamingPolicy);
Log.i(TAG,"构造函数:excluder:"+excluder);
Log.i(TAG,"构造函数:jsonAdapterFactory:"+jsonAdapterFactory);
}
/**
* 主要判断属性是否被包含在过滤的序列化和反序列化中
* @param f
* @param serialize
* @return
*/
public boolean excludeField(Field f, boolean serialize) {
return excludeField(f, serialize, excluder);
}
static boolean excludeField(Field f, boolean serialize, Excluder excluder) {
return !excluder.excludeClass(f.getType(), serialize) && !excluder.excludeField(f, serialize);
}
/**
* 获取属性对应全部的属性名(本身的属性名以及SerializedName上的属性)
* 1.通过Field.getAnnotation获取属性是否有SerializedName注解
* 2.若没有SerializedName注解 则直接将属性名转换为集合返回
* 若有SerializedName注解 则获取value值以及alternates数组
* 若alternates为空,则将value值转换为集合返回
* 若SerializedName不为空 则将value以及alternates转换为集合转换集合返回
* @param f
* @return
*/
private List<String> getFieldNames(Field f) {
Log.i("getFieldNames","----------------------------");
//1.获取属性上是否有SerializedName注解
SerializedName annotation = f.getAnnotation(SerializedName.class);
Log.i("getFieldNames","获取属性上是否有SerializedName注解:"+annotation);
//若没有SerializedName注解 则通过fieldNamingPolicy获取属性的名字 然后转换集合返回
if (annotation == null) {
String name = fieldNamingPolicy.translateName(f);
Log.i("getFieldNames","若没有SerializedName注解 则通过fieldNamingPolicy获取属性的名字 然后转换集合返回:"+fieldNamingPolicy+"-->"+name);
return Collections.singletonList(name);
}
//获取注解的值
String serializedName = annotation.value();
Log.i("getFieldNames","注解不为空 获取注解的值 :"+serializedName);
//获取注解的字段属性数组
String[] alternates = annotation.alternate();
Log.i("getFieldNames","注解不为空 获取注解的字段属性数组 :"+alternates.length);
//若alternates为空 则将serializedName转换为集合 进行返回
if (alternates.length == 0) {
Log.i("getFieldNames","若alternates为空 则将serializedName转换为集合 进行返回 :"+alternates.length);
return Collections.singletonList(serializedName);
}
//若alternates不为空 则将serializedName和alternates放入集合 进行返回
List<String> fieldNames = new ArrayList<String>(alternates.length + 1);
fieldNames.add(serializedName);
for (String alternate : alternates) {
fieldNames.add(alternate);
}
Log.i("getFieldNames","若alternates不为空 则将serializedName和alternates放入集合 进行返回 :"+fieldNames.size());
return fieldNames;
}
/**
* 1.在gson的getAdapter()中被调用
* 2.主要用于创建一个typeAdapter 进行write/read操作
* 3.操作步骤
* (1) 获取typetoken泛型的class 判断是否是object 若是直接退出
* (2) 通过 constructorConstructor.get(type) 获取ObjectConstructor对象 用于创建java bean对象
* (3) 通过getBoundFields()获取java bean所有的属性 放入map集合
* (4) 创建adapter 传入bjectConstructor和map
* (5) 返回这个adapter
* @param gson
* @param type
* @param <T>
* @return
*/
@Override public <T> TypeAdapter<T> create(Gson gson, final TypeToken<T> type) {
//获取typetoken泛型的class
Class<? super T> raw = type.getRawType();
Log.i(TAG,"create :"+type+"--》"+raw);
//若是object是父类 直接退出
if (!Object.class.isAssignableFrom(raw)) {
Log.i(TAG,"create Object是它的父类 直接退出");
return null; // it's a primitive!
}
//通过构造器工具的get方法获取对应ObjectConstructor 通过它可以获取泛型的实例对象
ObjectConstructor<T> constructor = constructorConstructor.get(type);
Log.i(TAG,"create 获取ObjectConstructor:"+constructor);
Log.i(TAG,"create new Adapter");
return new Adapter<T>(constructor, getBoundFields(gson, type, raw));
}
/**
* 创建BoundField 对象
* 1.根据属性的数据类型判断是否是基本数据类型 用于在读取数据时判断数据value为空时还是否需要设置
* 2.判断属性是否有jsonadapter注解 若有则通过jsonAdapterFactory.getTypeAdapter获取typeadapter
* 没有则通过gson.getAdapter()获取typeadapter
* 3.创建匿名内部类对象BoundField 将name/serialize/deserialize传递进去,并重写read/write方法
* @param context gson 用于获取typeadapter
* @param field java bean中对应的属性 用于获取jsonAdapter注解
* @param name 获取的属性的名称 不一定是java bean属性的name,可能是注解上的name
* @param fieldType 属性的类型声明 判断是否是基本数据类型
* @param serialize 是否可以序列化
* @param deserialize 是否也可以反序列化
* @return
*/
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());
Log.i(TAG,"createBoundField 判断属性是否是基本数据类型:"+field.getName()+"-->"+name+"--》"+fieldType.getRawType()+"->>"+isPrimitive);
// special casing primitives here saves ~5% on Android...
//获取属性是否含有JsonAdapter注解 自定义注解解析器
JsonAdapter annotation = field.getAnnotation(JsonAdapter.class);
TypeAdapter<?> mapped = null;
if (annotation != null) {
// Gson尝试获取该类型的TypeAdapter,这个方法我们后面也会继续提到。
mapped = jsonAdapterFactory.getTypeAdapter(
constructorConstructor, context, fieldType, annotation);
Log.i(TAG,"createBoundField 若含有JsonAdapter 通过jsonAdapterFactory尝试获取对应typeadapter:"+mapped);
}
final boolean jsonAdapterPresent = mapped != null;
Log.i(TAG,"createBoundField 是否已经获取到了自定义的typeadapter:"+jsonAdapterPresent);
//获取当前json串的一个name/value的name对应JavaBean里面的变量类型type,或者这个type对应的TypeAdpater类
Log.i(TAG,"createBoundField 是否没有自定义jsonadapter:"+mapped);
if (mapped == null) mapped = context.getAdapter(fieldType);;//获取对应的基本类型的
// final变量,便于内部类使用
final TypeAdapter<?> typeAdapter = mapped;
Log.i(TAG,"createBoundField 最后创建BoundField的内部类:"+name+"-->"+serialize+"-->"+deserialize+"-->"+(typeAdapter == TypeAdapters.STRING));
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 {
Log.i(TAG,"write: 拿到了value 开始真的写入");
//通过反射从java bean中获取对应属性的属性值
Object fieldValue = field.get(value);
Log.i(TAG,"write: fieldValue :"+field.getName()+"-->"+fieldValue+"--》"+jsonAdapterPresent);
//若该属性使用的是自定义jsonAdapter 则调用jsonadapter的write,反之使用TypeAdapterRuntimeTypeWrapper的write
TypeAdapter t = jsonAdapterPresent ? typeAdapter
: new TypeAdapterRuntimeTypeWrapper(context, typeAdapter, fieldType.getType());
Log.i(TAG,"write: TypeAdapter是哪一种 :"+t );
t.write(writer, fieldValue);
}
// ReflectiveTypeAdapter委托的Json读操作会调用到这里
@Override void read(JsonReader reader, Object value)
throws IOException, IllegalAccessException {
// 通过该属性的类型对应的TypeAdapter尝试读取json串
//如果是基础类型,则直接读取,
//如果是复合类型则递归之前的流程
//通过各种adapter就获取到对应的值
Object fieldValue = typeAdapter.read(reader); // 获取下一个jsontoken而不消耗它
//通过反射设置进去
if (fieldValue != null || !isPrimitive) {
field.set(value, fieldValue);//更新filed值
}
}
/**
* 判断boundfield是否可以写入
* @param value
* @return
* @throws IOException
* @throws IllegalAccessException
*/
@Override public boolean writeField(Object value) throws IOException, IllegalAccessException {
Log.i(TAG,"writeField: 判断属性是否可以写入:"+value);
//若是不可以序列化 则返回false
if (!serialized) return false;
//获取属性对应的属性值
Object fieldValue = field.get(value);
Log.i(TAG,"writeField:"+serialize+"--》"+field.getName()+"-->"+fieldValue+"-->"+value);
//若fieldValue==value 可能形成递归
return fieldValue != value; // avoid recursion for example for Throwable.cause
}
};
}
/**
* 作用:用于将java bean中的属性封装到BoundField中 然后以属性名为key BoundField为value放入map中
* 操作:
* 1.判断是否是接口 若是接口 直接返回
* 2.获取typetoken的泛型类型 也就是java bean的类型
* 3.通过while获取java object的类型以及父类型 若父类型是object 也就是顶级父类 表示我们遍历完成 没有对应的自定属性需要获取
* 4.若获取的class的真实类型不是object 表示是java bean是自定义类型或者自定义类型的父类型,可以通过反射获取属性
* 5.通过getDeclaredFields() 获取class所有的属性
* 6.遍历所有的属性,然后获取属性所对应的类型以及属性上面的注解属性数组(有多个)
* 7.将属性数组进行遍历 然后包装成BoundField 然后存储到map集合中
* 8.获取当前类型的父类型,继续循环
*
* @param context gson对象
* @param type java bean对象对应的typetoken
* @param raw java bean对象对应的class
* @return
*/
private Map<String, BoundField> getBoundFields(Gson context, TypeToken<?> type, Class<?> raw) {
Log.i("getBoundFields","开始返回BoundField集合");
Map<String, BoundField> result = new LinkedHashMap<String, BoundField>();// 创建一个Map结构,存放所有的BoundField
if (raw.isInterface()) {
Log.i("getBoundFields","raw 是接口");
return result;
}
//GsonAnnotation$SerializedNameBean
Type declaredType = type.getType();
Log.i("getBoundFields"," TypeToken getType:"+declaredType);
while (raw != Object.class) { // 如果类型是Object则结束循环
Field[] fields = raw.getDeclaredFields(); // 获取该类型的所有的内部属性
Log.i("getBoundFields","获取该类型的所有的内部属性:"+fields.length);
for (Field field : fields) {
boolean serialize = excludeField(field, true);
boolean deserialize = excludeField(field, false);
Log.i("getBoundFields","内部属性是否可以序列化和反序列化:"+field.getName()+"-->"+serialize+"--》"+deserialize);
if (!serialize && !deserialize) {
continue;
}
accessor.makeAccessible(field);
Type fieldType = $Gson$Types.resolve(type.getType(), raw, field.getGenericType());
Log.i("getBoundFields","resolve:"+type.getType()+"-->"+fieldType+"--》"+ field.getGenericType());
//一个注解上面由多个名字 以第一个作为序列化名
List<String> fieldNames = getFieldNames(field);// 获取该Filed的名字(Gson通过注解可以给一个属性多个解析名)
Log.i("getBoundFields","getFieldNames数组:"+field.getName()+"-->"+fieldNames.size());
//从SerializedNameBean获取到的属性数组是 name data1 data2 name1 c
//首先获取注解属性名 获取不到才使用属性本身的属性名
BoundField previous = null;
for (int i = 0, size = fieldNames.size(); i < size; ++i) {
String name = fieldNames.get(i);
Log.i("getBoundFields","遍历getFieldNames:"+name);
// 多个解析名,第一作为默认的序列化名称 只有第一个属性名才可以参与序列化操作
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);
Log.i("getBoundFields","createBoundField:"+boundField+"--》"+field.getName()+"-->"+name+"--》"+TypeToken.get(fieldType));
// 将BoundField放入Map中,获取被替换掉的value(如果有的话)
//将属性名称作为key,boundField作为value保存到result中
//返回值 判断是否已经添加过相同的数据类 若是的话 则抛异常 因为由多个相同的field name
BoundField replaced = result.put(name, boundField);
Log.i("getBoundFields","将属性名称作为key,boundField作为value保存到result中:"+replaced+"--》"+previous);
//如果之前解析过对应的这个值的话,这里就会导致previous不为空,从而报错
if (previous == null) previous = replaced;
}
// 做好记录
if (previous != null) {
// 如果previous != null证明出现了两个相同的Filed name,直接抛出错误
// 注:Gson不允许定义两个相同的名称的属性(父类和子类之间可能出现)
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();// 获取父类类型,最终会索引到Object.因为Object是所有对象的父类
Log.i("getBoundFields","获取父类类型,最终会索引到Object.因为Object是所有对象的父类:"+raw);
}
Log.i("getBoundFields","返回BoundField集合:"+result.size());
return result;
}
/**
* BoundField 抽象类
* 1.包装了属性名 以及是否可以序列化以及反序列化
* 2.抽象方法:
* writeField(Object value) 判断该值是否可以写入
* write(JsonWriter writer, Object value) 写入数据
* read(JsonReader reader, Object value) 读取数据
*/
static abstract class BoundField {
final String name;
final boolean serialized;
final boolean deserialized;
protected BoundField(String name, boolean serialized, boolean deserialized) {
this.name = name;
this.serialized = serialized;
this.deserialized = deserialized;
}
abstract boolean writeField(Object value) throws IOException, IllegalAccessException;
abstract void write(JsonWriter writer, Object value) throws IOException, IllegalAccessException;
abstract void read(JsonReader reader, Object value) throws IOException, IllegalAccessException;
}
/**
* 1.继承于typeAdapter
* 2.构造函数
* ObjectConstructor 用于创建java bean对象
* Map<String, BoundField> 用于存储属性名以及对应的一些配置
*
* @param <T>
*/
public static final class Adapter<T> extends TypeAdapter<T> {
private final ObjectConstructor<T> constructor;// 该复合类型的构造器,用于反射创建对象
private final Map<String, BoundField> boundFields;// 该类型内部的所有的Filed属性,都通过map存储起来
Adapter(ObjectConstructor<T> constructor, Map<String, BoundField> boundFields) {
this.constructor = constructor;
this.boundFields = boundFields;
Log.i(TAG,"Adapter new Adapter:"+constructor+"--》"+boundFields);
Set<Map.Entry<String, BoundField>> set = boundFields.entrySet();
Iterator<Map.Entry<String, BoundField>> iterator = set.iterator();
while (iterator.hasNext()){
Map.Entry<String, BoundField> data = iterator.next();
String key = data.getKey();
BoundField fieds = data.getValue();
Log.i(TAG,"boundFields:"+key+"-->"+fieds.name+"-->"+fieds.deserialized+"-->"+fieds.deserialized);
}
}
//JsonReader是Gson封装的对Json相关的操作类,可以依次读取json数据
@Override public T read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
//通过构造器
T instance = constructor.construct();
Log.i("fromJson","采用构造器是哪个:"+constructor+"-->"+instance);
try {
//将stackSize数组的第二个元素赋值为empty_object 将peek设置为peeked_none
in.beginObject();
//若peek的状态不是endObject/endArray 同时将peeked从PEEKED_NONE ->PEEKED_DOUBLE_QUOTED_NAME
while (in.hasNext()) {
//读取key值
String name = in.nextName();//开始逐个读取json串中的key
//根据json的key从boundFields取对应的BoundField
BoundField field = boundFields.get(name); // 通过key寻找对应的属性
if (field == null || !field.deserialized) {
//跳过对应的value 将其设置为null
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 public void write(JsonWriter out, T value) throws IOException {
Log.i(TAG,"进入写入:"+value);
if (value == null) {
out.nullValue();
return;
}
//开始写入 {
out.beginObject();
try {
for (BoundField boundField : boundFields.values()) {
if (boundField.writeField(value)) {
//给deferredName复制 无其他操作
out.name(boundField.name);
Log.i(TAG,"out 写入:"+boundField.name+"-->"+value);
boundField.write(out, value);
}
}
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
//写入结束 }
out.endObject();
}
}
}
ReflectiveTypeAdapterFactory的构造函数有四个参数
ConstructorConstructor:是一个专门根据tokenType的泛型类型来构建对应的泛型类型对象,用于在read过程中创建需要的真正的对象
FieldNamingStrategy:是属性的名称规则,默认就是将field的name作为属性名
JsonAdapterAnnotationTypeAdapterFactory:在Gson中对于属性和类都可以通过JsonAdapter注解定义一个自定义规则的解析器,若属性上含有JsonAdapter注解,则获取JsonAdapter的注解值作为该属性的typeAdapter;反之使用根据数据类型使用Gson内置的typeAdapter
Excluder:过滤器,用于根据一些规则来判断该Java对象中的。。属性是否可以参与序列化和反序列化
BoundField:是ReflectiveTypeAdapterFactory一个内部抽象类,它包装了属性的name以及该属性是否可以进行序列化和反序列化
name:标识了属性名
serialized:标识该属性是否可以序列化
deserialized:标识该属性是否可以反序列化
writeField(Object value) :抽象方法,判断该属性是否可以序列化
write(JsonWriter writer, Object value):抽象方法 用于数据的序列化操作
read(JsonReader reader, Object value):抽象方法 用于数据的反序列化操作
create()
在create方法中通过constructorConstructor.get(type)方法获取
ObjectConstructor对象,ObjectConstructor可以在read中创建Java
Object对象;然后调用getBoundFields()获取Java Object中所有的属
性,然后将一个个属性包装成getBoundFields()放入集合中,最后创
建一个自定义的TypeAdapter,将ObjectConstructor和Map传递进去
ReflectiveTypeAdapterFactory内部构建了一个TypeAdapter专门用来进行序列化和反序列的
constructor:ObjectConstructor类型的,用于在反序列化中(read)构建Java Object对象
boundFields:map集合,以属性名为key,以包装属性名的boundField为value
write(JsonWriter out, T value):用于序列化操作(Java Object转Json),在写入之前调用out.beginObject()方法,该方法主要用于写入json字符串的的"{"符号,之后遍历boundFields集合,判断每一个属性是否可以参与序列化,若可以,则调用out.name(boundField.name)设置当前的name,然后调用 boundField.write(out, value)进行写入,可以看到当调用toJson的TypeAdapter进行write的时候,最后还是调用boundField中write方法,在BoundField的write方法中通过反射从Java Object获取对应的属性值,之后通过JsonWrite将数据进行写入,集合遍历完成之后了,表示数据写入完成,最后调用out.endObject()写入结束符号"}",那么整个Java Object就被转换为一个标准的json形式的字符串了
read(JsonReader in):用于进行反序列化操作(Json转换为Java Object)。首先会调用constructor.construct()创建Java Object的实例对象,然后调用in.beginObject()设置状态值为EMPTY_OBJECT,JsonReader在读取的时候会根据不同的状态进行不同的操作,然后调用in.hasNext()
判断是否有下一个数据,若有的话调用in.nextName()获取name,然后调用boundFields.get(name)获取对应的BoundField,最后调用BoundField.read()进行反序列化,可以看到当调用fromJson的TypeAdapter进行read的时候,最后还是调用boundField中read方法,BoundField中通过反射给对应的field进行赋值。当所有的数据都写入完成之后,调用in.endObject()重置状态
getBoundFields()
主要用于对应属性最终的序列化和反序列化操作,在创建TypeAdapter时被调用。它会获取Java Object中的所有的属性,然后根据excluder来判断是否可以进行序列化和反序列化 ,之后将属性的属性名包装成一个BoundField对象,以属性名为key,以对应的BoundField为value,存储到map中 ,每一个属性都对应一种数据类型,都会有对应的TypeAdapter,即便是Java Object的属性是自定义类型的,也会使用再次使用ReflectiveTypeAdapterFactory的TypeAdapter,最终是所有的数据都会被拆分成各种对应的基本数据类型,调用对应的typeAdapter的read/write方法进行读写的
createBoundField()
主要根据属性创建一个对应的BoundField,在BoundField中重写write/read方法,在TypeAdapter的write/read中会遍历一个个BoundField,然后调用write/read进行序列化和反序列化操作
说明
- 1.首先在Gson的getAdapter()方法中会调用create的方法来创建TypeAdapter,在创建TypeAdapter时会调用getBoundFields()来将Java Object的属性一个个的封装成一个BoundField,存储到map集合中,以便于在write/read中使用
- 2.每一个属性都会构建一个BoundField,它封装了属性名以及标识它是否可以序列化和反序列化,同时重写了write/read方法进行真正的序列化和反序列化,同时每一个属性会根据对应的数据类型返回对应的TypeAdapter,在typeAdapter的read/write方法中调用JsonWrite/JsonReader进行数据的写入和读取
- 3.gson会调用返回的typeAdapter的read()方法进行反序列化。
- 4.调用constructor.construct()构建Java Object实例对象
- 5.调用in.beginObject()修改当前状态,因为在之前调用peek()方法将peek的状态修改为PEEKED_BEGIN_OBJECT,stack第一个位置的状态值为NONEMPTY_DOCUMENT,所以此时会把stack的第二个位置修改为JsonScope.EMPTY_OBJECT,p的状态值修改为PEEKED_NONE
- 6.while循环in.hasNext()判断当前读取状态是否已经结束,若没有则获取属性名以及对应的属性值.会调用doPeek()方法,若读取到双引号,则 p的状态改为PEEKED_DOUBLE_QUOTED_NAME;若读取到“}”,则 p的状态改为PEEKED_END_OBJECT
- 7.调用in.nextName()获取json中的key值,当前第二个位置的状态值为JsonScope.EMPTY_OBJECT,同时将p的状态修改为PEEKED_DOUBLE_QUOTED_NAME,之后根据此状态值调用nextQuotedValue(’"’)取出key值,并记录位置key后面双引号的位置,最后将peeked的状态值改为PEEKED_NONE
- 8.获取到key值后调用boundFields.get(name)从map集合中获取对应的BoundField,之后调用BoundField.read()进行对应值的读取
- 9.在BoundField的read()方法中,会调用typeAdapter.read(reader)读取出对应的值,它会和取key值一样,也是调用nextQuotedValue(’"’)取出value值,因为之前已经记录双引号的位置,所以会向后移查找下一个双引号的位置,这样就可以获取到value的值,再次记录位置
- 10.获取value值后调用field.set(value, fieldValue)方法过反射的方式将值写入到Java Bean中,之后再次调用hasNext()不断的循环,直到读取到json字符串的结束符号“}”时,p的状态该为PEEKED_END_OBJECT,那么表示所有的数据已经读取完成
- 11.当所有的值取出来后调用in.endObject()将peek设置为peeked_none,并将pathNames数组中stackSize位置设置为null
- 12.最后将Java Object实例对象返回出去,这就是从json字符串中读取一个Object的流程
public class JsonReader implements Closeable {
private static final long MIN_INCOMPLETE_INTEGER = Long.MIN_VALUE / 10;
private static final int PEEKED_NONE = 0;
private static final int PEEKED_BEGIN_OBJECT = 1;
private static final int PEEKED_END_OBJECT = 2;
private static final int PEEKED_BEGIN_ARRAY = 3;
private static final int PEEKED_END_ARRAY = 4;
private static final int PEEKED_TRUE = 5;
private static final int PEEKED_FALSE = 6;
private static final int PEEKED_NULL = 7;
private static final int PEEKED_SINGLE_QUOTED = 8;
private static final int PEEKED_DOUBLE_QUOTED = 9;
private static final int PEEKED_UNQUOTED = 10;
/** When this is returned, the string value is stored in peekedString. */
private static final int PEEKED_BUFFERED = 11;
private static final int PEEKED_SINGLE_QUOTED_NAME = 12;
private static final int PEEKED_DOUBLE_QUOTED_NAME = 13;
private static final int PEEKED_UNQUOTED_NAME = 14;
/** When this is returned, the integer value is stored in peekedLong. */
private static final int PEEKED_LONG = 15;
private static final int PEEKED_NUMBER = 16;
private static final int PEEKED_EOF = 17;
/* State machine when parsing numbers */
private static final int NUMBER_CHAR_NONE = 0;
private static final int NUMBER_CHAR_SIGN = 1;
private static final int NUMBER_CHAR_DIGIT = 2;
private static final int NUMBER_CHAR_DECIMAL = 3;
private static final int NUMBER_CHAR_FRACTION_DIGIT = 4;
private static final int NUMBER_CHAR_EXP_E = 5;
private static final int NUMBER_CHAR_EXP_SIGN = 6;
private static final int NUMBER_CHAR_EXP_DIGIT = 7;
/** The input JSON. */
private final Reader in;
/** True to accept non-spec compliant JSON */
private boolean lenient = false;
/**
* Use a manual buffer to easily read and unread upcoming characters, and
* also so we can create strings without an intermediate StringBuilder.
* We decode literals directly out of this buffer, so it must be at least as
* long as the longest token that can be reported as a number.
*/
private final char[] buffer = new char[1024];
private int pos = 0;
private int limit = 0;
private int lineNumber = 0;
private int lineStart = 0;
int peeked = PEEKED_NONE;
/**
* A peeked value that was composed entirely of digits with an optional
* leading dash. Positive values may not have a leading 0.
*/
private long peekedLong;
/**
* The number of characters in a peeked number literal. Increment 'pos' by
* this after reading a number.
*/
private int peekedNumberLength;
/**
* A peeked string that should be parsed on the next double, long or string.
* This is populated before a numeric value is parsed and used if that parsing
* fails.
*/
private String peekedString;
/*
* The nesting stack. Using a manual array rather than an ArrayList saves 20%.
*/
private int[] stack = new int[32];
private int stackSize = 0;
{
stack[stackSize++] = JsonScope.EMPTY_DOCUMENT;
}
/*
* The path members. It corresponds directly to stack: At indices where the
* stack contains an object (EMPTY_OBJECT, DANGLING_NAME or NONEMPTY_OBJECT),
* pathNames contains the name at this scope. Where it contains an array
* (EMPTY_ARRAY, NONEMPTY_ARRAY) pathIndices contains the current index in
* that array. Otherwise the value is undefined, and we take advantage of that
* by incrementing pathIndices when doing so isn't useful.
*/
//存储json中key值
private String[] pathNames = new String[32];
private int[] pathIndices = new int[32];
/**
* Creates a new instance that reads a JSON-encoded stream from {@code in}.
*/
public JsonReader(Reader in) {
if (in == null) {
throw new NullPointerException("in == null");
}
this.in = in;
}
public JsonToken peek() throws IOException {
int p = peeked;
Log.i("fromJson","peek:"+p);
if (p == PEEKED_NONE) {
p = doPeek();
Log.i("fromJson","peek doPeek:"+p);
}
// PEEKED_BEGIN_OBJECT
//PEEKED_UNQUOTED
switch (p) {
case PEEKED_BEGIN_OBJECT://文档开始
Log.i("fromJson","peek:PEEKED_BEGIN_OBJECT");
return JsonToken.BEGIN_OBJECT;
case PEEKED_END_OBJECT:
Log.i("fromJson","peek:PEEKED_BEGIN_OBJECT");
return JsonToken.END_OBJECT;
case PEEKED_BEGIN_ARRAY:
Log.i("fromJson","peek:PEEKED_BEGIN_ARRAY");
return JsonToken.BEGIN_ARRAY;
case PEEKED_END_ARRAY:
Log.i("fromJson","peek:PEEKED_END_ARRAY");
return JsonToken.END_ARRAY;
case PEEKED_SINGLE_QUOTED_NAME:
case PEEKED_DOUBLE_QUOTED_NAME:
case PEEKED_UNQUOTED_NAME:
Log.i("fromJson","peek:PEEKED_SINGLE_QUOTED_NAME");
return JsonToken.NAME;
case PEEKED_TRUE:
case PEEKED_FALSE:
Log.i("fromJson","peek:PEEKED_TRUE");
return JsonToken.BOOLEAN;
case PEEKED_NULL:
Log.i("fromJson","peek:PEEKED_NULL");
return JsonToken.NULL;
case PEEKED_SINGLE_QUOTED:
case PEEKED_DOUBLE_QUOTED:
case PEEKED_UNQUOTED:
case PEEKED_BUFFERED:
Log.i("fromJson","peek:PEEKED_SINGLE_QUOTED");
return JsonToken.STRING;
case PEEKED_LONG:
case PEEKED_NUMBER:
Log.i("fromJson","peek:PEEKED_LONG");
return JsonToken.NUMBER;
case PEEKED_EOF:
Log.i("fromJson","peek: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,即只有第一个元素是有效的
//第一次取数据是6
int peekStack = stack[stackSize - 1];
Log.i("fromJson","doPeek peekStack:"+stackSize+" "+peekStack);
//JsonScope.EMPTY_ARRAY = 1
if (peekStack == JsonScope.EMPTY_ARRAY) {
//JsonScope.NONEMPTY_ARRAY = 2
stack[stackSize - 1] = JsonScope.NONEMPTY_ARRAY;
Log.i("fromJson","doPeek EMPTY_ARRAY-》NONEMPTY_ARRAY");
} else if (peekStack == JsonScope.NONEMPTY_ARRAY) {
//在第一次调用 nextNonWhitespace(true) 方法的时候,json 字符串会被转存为一个 char 数组
//该方法以 int 值的形式返回下一个要解析的 char 对象
int c = nextNonWhitespace(true);
switch (c) {
case ']':
Log.i("fromJson","doPeek NONEMPTY_ARRAY-》PEEKED_END_ARRAY");
//peeked 是 JsonReader 中最重要的用来状态控制的 int 变量
//peeker 和 stack 会协同控制 JsonReader 的逻辑行为
return peeked = PEEKED_END_ARRAY; //PEEKED_END_ARRAY = 4
case ';':
//检查标准协议选项,json 标准中的符号没有分号
//所以在 lenient = false 的时候就会报错
Log.i("fromJson","doPeek checkLenient ;");
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;
Log.i("fromJson","doPeek EMPTY_OBJECT//NONEMPTY_OBJECT:"+stack[stackSize - 1] );
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;
Log.i("fromJson","doPeek DANGLING_NAME:"+stack[stackSize - 1] );
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;
Log.i("fromJson","doPeek EMPTY_DOCUMENT:"+stack[stackSize - 1] );
} else if (peekStack == JsonScope.NONEMPTY_DOCUMENT) {
int c = nextNonWhitespace(false);
if (c == -1) {
return peeked = PEEKED_EOF;
} else {
checkLenient();
pos--;
}
Log.i("fromJson","doPeek NONEMPTY_DOCUMENT:"+stack[stackSize - 1] );
//JsonScope.CLOSED = 8
} else if (peekStack == JsonScope.CLOSED) {
throw new IllegalStateException("JsonReader is closed");
}
//在这里获取到了下一个要解析的 char 的 int 值
int c = nextNonWhitespace(true);
Log.i("fromJson","doPeek nextNonWhitespace:"+c );
//进入 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,证明下一个确实是特殊字符
Log.i("fromJson","doPeek 不等于 PEEKED_NONE,证明下一个确实是特殊字符:"+result );
return result;
}
//peekNumber() 方法和上述 peekKeyword() 方法很类似
//用于判断下一个要处理的字符串是否是数字
result = peekNumber();
if (result != PEEKED_NONE) {
Log.i("fromJson","doPeek 用于判断下一个要处理的字符串是否是数字:"+result );
return result;
}
//isLiteral(buffer[pos]) 用于判断下一个字符是否是特殊符
//比如 换行符、井号、括号 等
//如果是 换行符 的话这里就会抛出错误
if (!isLiteral(buffer[pos])) {
Log.i("fromJson","doPeek 如果是 换行符 的话这里就会抛出错误:"+result );
throw syntaxError("Expected value");
}
checkLenient();
Log.i("fromJson","doPeek 如果是 换行符 的话这里就会抛出错误:"+result+"-->"+peeked );
return peeked = PEEKED_UNQUOTED; //PEEKED_UNQUOTED = 10
}
/**
* Returns true if the current array or object has another element.
*/
public boolean hasNext() throws IOException {
int p = peeked;
if (p == PEEKED_NONE) {
p = doPeek();
}
return p != PEEKED_END_OBJECT && p != PEEKED_END_ARRAY;
}
/**
* Returns the {@link com.google.gson.stream.JsonToken#STRING string} value of the next token,
* consuming it. If the next token is a number, this method will return its
* string form.
*
* @throws IllegalStateException if the next token is not a string or if
* this reader is closed.
*/
public String nextString() throws IOException {
int p = peeked;
if (p == PEEKED_NONE) {
p = doPeek();
}
String result;
if (p == PEEKED_UNQUOTED) {
result = nextUnquotedValue();
} else if (p == PEEKED_SINGLE_QUOTED) {
result = nextQuotedValue('\'');
} else if (p == PEEKED_DOUBLE_QUOTED) {
result = nextQuotedValue('"');
} else if (p == PEEKED_BUFFERED) {
result = peekedString;
peekedString = null;
} else if (p == PEEKED_LONG) {
result = Long.toString(peekedLong);
} else if (p == PEEKED_NUMBER) {
result = new String(buffer, pos, peekedNumberLength);
pos += peekedNumberLength;
} else {
throw new IllegalStateException("Expected a string but was " + peek() + locationString());
}
peeked = PEEKED_NONE;
pathIndices[stackSize - 1]++;
return result;
}
/**
* Returns the {@link com.google.gson.stream.JsonToken#BOOLEAN boolean} value of the next token,
* consuming it.
*
* @throws IllegalStateException if the next token is not a boolean or if
* this reader is closed.
*/
public boolean nextBoolean() throws IOException {
int p = peeked;
if (p == PEEKED_NONE) {
p = doPeek();
}
if (p == PEEKED_TRUE) {
peeked = PEEKED_NONE;
pathIndices[stackSize - 1]++;
return true;
} else if (p == PEEKED_FALSE) {
peeked = PEEKED_NONE;
pathIndices[stackSize - 1]++;
return false;
}
throw new IllegalStateException("Expected a boolean but was " + peek() + locationString());
}
/**
* Consumes the next token from the JSON stream and asserts that it is a
* literal null.
*
* @throws IllegalStateException if the next token is not null or if this
* reader is closed.
*/
public void nextNull() throws IOException {
int p = peeked;
if (p == PEEKED_NONE) {
p = doPeek();
}
if (p == PEEKED_NULL) {
peeked = PEEKED_NONE;
pathIndices[stackSize - 1]++;
} else {
throw new IllegalStateException("Expected null but was " + peek() + locationString());
}
}
public String nextName() throws IOException {
//老样子进行 peeked 的状态获取
int p = peeked;
Log.i("nextName","peeked11:"+p);
//此时是PEEK_BEGIN_OBJECT
if (p == PEEKED_NONE) {
p = doPeek();
}
Log.i("nextName","peeked22:"+p);
String result;
//在这里通过 if 语句和 peeked 定位 json 的 key 是用单引号还是双引号包裹的
//result 就是 key 的字符串
if (p == PEEKED_UNQUOTED_NAME) {
result = nextUnquotedValue();
Log.i("nextName","PEEKED_UNQUOTED_NAME:"+result);
} else if (p == PEEKED_SINGLE_QUOTED_NAME) {
result = nextQuotedValue('\'');
Log.i("nextName","PEEKED_SINGLE_QUOTED_NAME:"+result);
} else if (p == PEEKED_DOUBLE_QUOTED_NAME) {
//根据冒号取直
result = nextQuotedValue('"');
Log.i("nextName","PEEKED_DOUBLE_QUOTED_NAME:"+result);
} else {
throw new IllegalStateException("Expected a name but was " + peek() + locationString());
}
//将 peeked 状态初始化
peeked = PEEKED_NONE;
//pathNames 是一个用来储存所有 key 的字符串的数组
pathNames[stackSize - 1] = result;
Log.i("nextName","pathNames:"+pathNames.length+"-->"+result
);
for (int i=0;i<pathNames.length;i++){
Log.i("nextName","nextName结束之后pathNames的数据:"+i+"-->"+pathNames[i]);
}
return result;
}
public void beginObject() throws IOException {
//第一次是1
int p = peeked;
Log.i("fromJson","beginObject:"+p);
//初始化时 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;
Log.i("fromJson","beginObject PEEKED_BEGIN_OBJECT:"+peeked+"--》"+stackSize);
for (int i=0;i<stack.length;i++){
Log.i("fromJson","beginObject stackSize:"+stack[i]);
}
} else {
throw new IllegalStateException("Expected BEGIN_OBJECT but was " + peek() + locationString());
}
}
public void beginArray() throws IOException {
int p = peeked;
if (p == PEEKED_NONE) {
p = doPeek();
}
if (p == PEEKED_BEGIN_ARRAY) {
push(JsonScope.EMPTY_ARRAY);
pathIndices[stackSize - 1] = 0;
peeked = PEEKED_NONE;
} else {
throw new IllegalStateException("Expected BEGIN_ARRAY but was " + peek() + locationString());
}
}
/**
* Consumes the next token from the JSON stream and asserts that it is the
* end of the current array.
*/
public void endArray() throws IOException {
int p = peeked;
if (p == PEEKED_NONE) {
p = doPeek();
}
if (p == PEEKED_END_ARRAY) {
stackSize--;
pathIndices[stackSize - 1]++;
peeked = PEEKED_NONE;
} else {
throw new IllegalStateException("Expected END_ARRAY but was " + peek() + locationString());
}
}
public void endObject() throws IOException {
int p = peeked;
Log.i("fromJson","endObject11:"+p+"-->"+stackSize);
if (p == PEEKED_NONE) {
p = doPeek();
}
Log.i("fromJson","endObject22:"+p+"-_>"+stackSize);
if (p == PEEKED_END_OBJECT) {
stackSize--;
pathNames[stackSize] = null; // Free the last path name so that it can be garbage collected!
pathIndices[stackSize - 1]++;
peeked = PEEKED_NONE;
} else {
throw new IllegalStateException("Expected END_OBJECT but was " + peek() + locationString());
}
}
.....这只是部分源码....
}
说明
Reader in
由构造函数传递进来,里面解析了Json字符串的数据
int peek
int类型,记录当前的操作状态。默认为PEEK_NONE
int[] stack
32位的int数组 记录对Json文档操作的状态,配合stackSize使用。stack 是一个定义在 JsonReader 中的 int 数组,作为 JsonReader 的指令集存在,用于控制变量 peeked 的状态
在 JsonReader 初始化的时候会将 stack 的第一个元素变成6,其余均为0
6的意思根据官方注释为 "No object or array has been started"(还没开始读取对象或列表)
6作为常量保存在 JsonScope 中,JsonScope 中还保存了很多代表指令的常量,下列会用到
stackSize 是 stack 的有效元素计数器,初始化时 stackSize = 1,即只有第一个元素是有效的,第一次取数据是6
peek()
根据peek的状态,判断下一个状态时什么
doPeek()
从stack数组中获取stackSize-1位置的状态值,然后根据状态值读取文档,根据读取的数据修改peeked的状态,标识文档的读取状态
hasNext()
判断peek的值,若是PEEKED_NONE,会调用doPeek()然后根据stack数组在stackSize - 1的值来进行一些操作,然后在修改peeke的状态值,最后根据peeked是否是PEEKED_END_OBJECT/PEEKED_END_ARRAY来判断json是否已经被读取完了,这个在反序列化时被调用,可以用来判断文档是否已经读取完成了
nextString()
从json字符串中取出属性所对应的属性值数据并以String类型进行返回,一般用于取出json字符串对应属性名的属性value值
nextBoolean()
从json字符串中取出属性所对应的属性值数据并以Boolean类型进行返回,一般用于取出json字符串对应属性名的属性value值
nextNull()
消耗JSON流中的下一个令牌,并断言它是一个literal null,一般用于取出json字符串对应属性名的属性value值
nextName()
获取Json字符串中的key值,当要获取对应的属性名时调用该方法
beginObject()
将stack数组的stackSize-1的位置的状态修改为JsonScope.EMPTY_OBJECT,表示读取json文档开始,若json字符串是一个Object,需在读取json字符串的属性名/属性值前调用
beginArray()
将stack数组的stackSize-1的位置的状态修改为JsonScope.EMPTY_ARRAY,表示读取json文档开始,若json字符串是一个Array,需在读取json字符串的属性名/属性值前调用
endObject()
重置状态,将peeked的状态修改为peeked,表示读取json文档完成,若json字符串是一个Object,需在读取json字符串的属性名/属性值完后调用该方法
endArray()
重置状态,将peeked的状态修改为peeked,表示读取json文档完成,若json字符串是一个Object,需在读取json字符串的属性名/属性值完后调用
nextQuotedValue()
以传递的char为参照,根据pos的位置从json字符串中向后查找,若查找到了以这个基础位置继续向后查找和char相同的字符的位置,然后返回截取到这两个位置之间的数据,在json字符串中获取属性名,属性值都是通过该方法获取到的