留坑埠戳,請慎讀
起因
剛開始接觸Json的時候,Json轉(zhuǎn)換比較簡單瘟判,后臺傳來一段數(shù)據(jù)怨绣,
{
"name": "錢"
"age": 18
"sex":0 //0-男 1-女
}
我只要對著這些屬性創(chuàng)建一個類,類的field對應(yīng)數(shù)據(jù)的屬性即可
public class Person {
String name;
int age;
int sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
}
然后使用Gson將數(shù)據(jù)轉(zhuǎn)換成class即可
Gson gson = new Gson();
Person person = gson.fromJson(jsonText, Person.class);
依葫蘆畫瓢拷获,久而久之篮撑,就產(chǎn)生一種懶惰感。這種懶惰感一直持續(xù)到我遇到這個JsonText:
[{
"name": "錢"
"age": 18
"sex":0 //0-男 1-女
},
{
"name": "哈哈"
"age": 19
"sex":0 //0-男 1-女
}]
嗯匆瓜?這種樣式怎么以前沒見過赢笨,是后臺大哥傳錯了?驮吱?茧妒?我這個人有個毛病,就是能照著葫蘆畫瓢絕對不會深究其原理糠馆。無盡的恐懼在我心里彌漫嘶伟,但我這個人也有個“優(yōu)點”----讓我不爽的都去死。于是就去讀源碼了又碌。九昧。。
Gson源碼解析
Gson解析String有兩個方法
方法1:
public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException {
Object object = fromJson(json, (Type) classOfT);//invoke method2
return Primitives.wrap(classOfT).cast(object);
}
方法2
public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException {
if (json == null) {
return null;
}
StringReader reader = new StringReader(json);
T target = (T) fromJson(reader, typeOfT);
return target;
}
仔細(xì)的同學(xué)會發(fā)現(xiàn)方法1也是調(diào)用方法2毕匀,也就是說最終都是調(diào)用方法2. 那這個時候問題就來這個Type是什么東西铸鹰?補(bǔ)補(bǔ)基礎(chǔ)Java反射--Type
補(bǔ)充完之后,回到 StringReader reader = new StringReader(json);
這一行皂岔。繼續(xù)之前請先思考一個問題:如果讓你寫一個Json解析器,你會怎么寫?我想無外乎幾種情況:
-使用正則表達(dá)式
-逐個分析String的字符
while(isEnd(string)){
switch(getCharOf(string)):
case "{":
//start a class
case "}"
//end a class //像不像XML解析
}
-其他
所以不要以為StringReader
這個類很陌生蔗彤,其實他就是幫我們做getChar(String)
這一操作洲鸠,他有兩個方法
public int read() //一次只讀一個字符
public long skip(long ns) //跳過指定長度的字符
下面貼執(zhí)行代碼,不然貼一段解釋一段太亂
public <T> T fromJson(String json, Class<T> classOfT){
Object object = fromJson(json, (Type) classOfT);
}
public <T> T fromJson(String json, Type typeOfT) {
StringReader reader = new StringReader(json);
}
public <T> T fromJson(Reader json, Type typeOfT) {
JsonReader jsonReader = newJsonReader(json);
T object = (T) fromJson(jsonReader, typeOfT);
}
public <T> T fromJson(JsonReader reader, Type typeOfT) {
TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);
TypeAdapter<T> typeAdapter = getAdapter(typeToken);
T object = typeAdapter.read(reader);
}
最終調(diào)用了 getAdapter(typeToken).read(reader), 這個TypeAdapter實際上是ReflectiveTypeAdapterFactory的內(nèi)部類Adapter教馆,其read()方法為:
@Override
public T read(JsonReader in) throws IOException {
T instance = constructor.construct();//使用反射創(chuàng)建class的實例
while (in.hasNext()) {
String name = in.nextName();//get attribute name
BoundField field = boundFields.get(name);//get field by name
if (field == null || !field.deserialized) in.skipValue();
else field.read(in, instance);
}
return instance;
}
while內(nèi)部的代碼從名字就能看出來逊谋,一個是獲取JsonText的屬性,另一個是根據(jù)屬性的名字去查找Class中的Field土铺,如果沒有找到則跳過胶滋,找到則為instance添加field,最后返回Instance悲敷。
至此究恤,Gson解析完畢。當(dāng)然還有里面有好多坑后德,以后再補(bǔ)部宿。