文章異常囉嗦且繞彎。html
Gson 版本 : gson 2.8.5java
IDE : idea 2018.3sql
Gson 是谷歌開源的 java json 解析工具。市場上同類的開源產品還有 Fastjson、Jackson、json-lib等。json
其實幾款產品的差異都很細微,Gson 有谷歌的信仰加成,因此在這裏進行一次源碼分析。api
package ioc; /** * java bean */ public class Person { private String name; private Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
import com.google.gson.Gson; public class JsonTest { public static void main(String[] args){ //示例 json 字符串 String json = "{" + " \"name\": \"zhangsan\"," + " \"age\": 11" + "}"; //初始化解析器 Gson gson = new Gson(); //json to bean Person person = gson.fromJson(json,Person.class); System.out.println(person.getName()); System.out.println(person.getAge()); //bean to json String json2 = gson.toJson(person); System.out.println(json2); } }
該 part 的起點:ide
Gson gson = new Gson();
追蹤 Gson 的無參構造器:工具
//Gson.class 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.class Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingStrategy, final 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) { //排除器,在序列化對象的時候會根據使用者設置的規則排除一些數據 //排除策略須要使用者自行實現 ExclusionStrategy 接口來制定 this.excluder = excluder; //fieldNamingStrategy 負責命名規則的肯定(好比 大駝峯命名、小駝峯命名、下劃線命名 等) //選擇不一樣的 fieldNamingStrategy 會在輸出 json 字符串的時候把字段名稱轉成不一樣的命名形式 //此處的值能夠直接選擇 FieldNamingPolicy 枚舉類中的已經存儲的策略,也能夠自行實現 FieldNamingStrategy 接口 //此處默認爲 FieldNamingPolicy.IDENTITY,即不改變 this.fieldNamingStrategy = fieldNamingStrategy; //instanceCreators 是一個用來存儲實現了 InstanceCreator 接口的對象的 map //每個 InstanceCreator 的實現類用來反射獲取一種特定類型的 bean 對象 //InstanceCreator 在 Gson 中沒有實現類,使用者能夠自行定製 //此處爲空 map this.instanceCreators = instanceCreators; //ConstructorConstructor 用來統一調度 instanceCreators this.constructorConstructor = new ConstructorConstructor(instanceCreators); //serializeNulls 是一個 boolean 類型的對象,用以表示是否支持空對象的序列化 //此處傳入的是 DEFAULT_SERIALIZE_NULLS,值爲 false,是一個定義在 Gson 中的常量 this.serializeNulls = serializeNulls; //將 Map 序列化的過程當中,會存在一個問題,即 Map 的 key 值是一個複雜對象(java bean 等) //若是 complexMapKeySerialization 設置爲 false,則直接調用對象的 toString() 方法獲取字符串 //設置爲 true 的狀況下會去嘗試解析此對象,通常狀況下要配合特定的 TypeAdapter 使用 //默認爲 false this.complexMapKeySerialization = complexMapKeySerialization; //是否要生成不可執行的 json //默認爲 false this.generateNonExecutableJson = generateNonExecutableGson; //是否對 html 進行編碼,即對部分符號進行轉義(=、<、> 等) //默認爲 true this.htmlSafe = htmlSafe; //在輸出的時候格式化 json //默認爲 false this.prettyPrinting = prettyPrinting; //設置 json 的自定義標準 //默認 false ,即爲 json 標準的數據格式 this.lenient = lenient; //用於支持 float 類型的特殊值,好比 Infinity(無窮大) 或 -Infinity(負無窮大) 等 //默認爲 false this.serializeSpecialFloatingPointValues = serializeSpecialFloatingPointValues; //設置對 long 類型的變量,是解析成字符串仍是解析爲 long 類型 //默認爲解析成 long 類型 this.longSerializationPolicy = longSerializationPolicy; //如下三行用於設置日期格式和時間格式 //datePattern 是日期和時間的字符串格式表達,在此處爲 null //dateStyle 與 timeStyle 爲日期和時間格式的編碼 //以 int 常量形式存放在 java.text.DateFormat 中 //此處均爲默認值 //須要注意的是默認狀況下 Gson 的日期解析不太符合國人的習慣 this.datePattern = datePattern; this.dateStyle = dateStyle; this.timeStyle = timeStyle; //此處爲空 this.builderFactories = builderFactories; //此處爲空 this.builderHierarchyFactories = builderHierarchyFactories; //TypeAdapter 是一個接口,用於序列化和反序列化某種特定的類型 //TypeAdapterFactory 是 TypeAdapter 的包裝類 List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>(); //TypeAdapters 是 TypeAdapter 和 TypeAdapterFactory 的通用工具類 //處理 JsonElement 類型對象的 TypeAdapterFactory //JsonElement 是 Gson 工具包中的一個類 factories.add(TypeAdapters.JSON_ELEMENT_FACTORY); //處理 Object 類型對象的 TypeAdapterFactory factories.add(ObjectTypeAdapter.FACTORY); //excluder 是一個省略了類型的 TypeAdapterFactory //根據官方註釋,excluder 須要先於全部使用者自定義的 TypeAdapterFactory 去執行 factories.add(excluder); //使用者自定義的 TypeAdapterFactory factories.addAll(factoriesToBeAdded); //處理 String 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.STRING_FACTORY); //處理 Integer / int 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.INTEGER_FACTORY); //處理 Boolean / boolean 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.BOOLEAN_FACTORY); //處理 Byte / byte 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.BYTE_FACTORY); //處理 Short / short 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.SHORT_FACTORY); //處理 Long / long 類型對象的 TypeAdapterFactory TypeAdapter<Number> longAdapter = longAdapter(longSerializationPolicy); factories.add(TypeAdapters.newFactory(long.class, Long.class, longAdapter)); //處理 Double / double 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.newFactory(double.class, Double.class, doubleAdapter(serializeSpecialFloatingPointValues))); //處理 Float / float 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.newFactory(float.class, Float.class, floatAdapter(serializeSpecialFloatingPointValues))); //處理 Number 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.NUMBER_FACTORY); //處理 AtomicInteger 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.ATOMIC_INTEGER_FACTORY); //處理 AtomicBoolean 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.ATOMIC_BOOLEAN_FACTORY); //處理 AtomicBoolean 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.newFactory(AtomicLong.class, atomicLongAdapter(longAdapter))); //處理 AtomicLongArray 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.newFactory(AtomicLongArray.class, atomicLongArrayAdapter(longAdapter))); //處理 AtomicIntegerArray 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.ATOMIC_INTEGER_ARRAY_FACTORY); //處理 Character / char 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.CHARACTER_FACTORY); //處理 StringBuilder 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.STRING_BUILDER_FACTORY); //處理 StringBuffer 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.STRING_BUFFER_FACTORY); //處理 BigDecimal 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.newFactory(BigDecimal.class, TypeAdapters.BIG_DECIMAL)); //處理 BigInteger 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.newFactory(BigInteger.class, TypeAdapters.BIG_INTEGER)); //處理 URL 類型對象的 TypeAdapterFactory //java.net.URL factories.add(TypeAdapters.URL_FACTORY); //處理 URI 類型對象的 TypeAdapterFactory //java.net.URI factories.add(TypeAdapters.URI_FACTORY); //處理 UUID 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.UUID_FACTORY); //處理 Currency 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.CURRENCY_FACTORY); //處理 Locale 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.LOCALE_FACTORY); //處理 InetAddress 類型對象的 TypeAdapterFactory //java.net.InetAddress factories.add(TypeAdapters.INET_ADDRESS_FACTORY); //處理 BitSet 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.BIT_SET_FACTORY); //處理 Date 類型對象的 TypeAdapterFactory //java.util.Date factories.add(DateTypeAdapter.FACTORY); //處理 Calendar 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.CALENDAR_FACTORY); //處理 Time 類型對象的 TypeAdapterFactory factories.add(TimeTypeAdapter.FACTORY); //處理 Date 類型對象的 TypeAdapterFactory //java.sql.Date factories.add(SqlDateTypeAdapter.FACTORY); //處理 Timestamp 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.TIMESTAMP_FACTORY); //處理 Array 類型對象的 TypeAdapterFactory factories.add(ArrayTypeAdapter.FACTORY); //處理 Class 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.CLASS_FACTORY); //處理 Collection 類型對象的 TypeAdapterFactory factories.add(new CollectionTypeAdapterFactory(constructorConstructor)); //處理 Map 類型對象的 TypeAdapterFactory //會受到 complexMapKeySerialization 的影響 factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization)); //處理 JsonAdapter 類型對象的 TypeAdapterFactory //JsonAdapter 是一個 Gson 中的註解 this.jsonAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor); factories.add(jsonAdapterFactory); //處理 Enum 類型對象的 TypeAdapterFactory factories.add(TypeAdapters.ENUM_FACTORY); //反射分解對象的 TypeAdapterFactory factories.add(new ReflectiveTypeAdapterFactory( constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory)); this.factories = Collections.unmodifiableList(factories); }
從這裏能夠看出,Gson 的初始化時期提供了很是豐富的設置選項。ui
設置 Gson 的這些選項須要經過 GsonBuilder :this
Gson gson = new GsonBuilder() //如下方法均爲設置 excluder //設置版本號 .setVersion(1) //設置忽略某種修飾詞修飾的變量 //此處忽略 protected 修飾的變量 .excludeFieldsWithModifiers(Modifier.PROTECTED) //設置使用 Expose 註解,用於忽略某個字段 //默認狀況下是不使用 Expose 註解的 .excludeFieldsWithoutExposeAnnotation() //設置不序列化內部類 .disableInnerClassSerialization() //批量添加序列化時使用的排除策略 //此方法爲不定參方法 .setExclusionStrategies(exclusionStrategy) //添加一個序列化時使用的排除策略 .addSerializationExclusionStrategy(exclusionStrategy) //添加一個反序列化時使用的排除策略 .addDeserializationExclusionStrategy(exclusionStrategy) //本質上如下三個方法均爲設置 TypeAdapter .registerTypeAdapter(String.class, TypeAdapters.STRING) .registerTypeAdapterFactory(TypeAdapters.STRING_FACTORY) .registerTypeHierarchyAdapter(String.class, TypeAdapters.STRING) //設置 dateStyle、datePattern、timeStyle .setDateFormat("yyyy-MM-dd HH:mm:ss") .setDateFormat(DateFormat.DATE_FIELD) .setDateFormat(DateFormat.DATE_FIELD,DateFormat.AM_PM_FIELD) //如下兩個方法本質上是同樣的,均爲設置 fieldNamingPolicy 屬性 .setFieldNamingPolicy(FieldNamingPolicy.IDENTITY) .setFieldNamingStrategy(FieldNamingPolicy.IDENTITY) //設置 complexMapKeySerialization = true .enableComplexMapKeySerialization() //設置 longSerializationPolicy = LongSerializationPolicy.STRING //即 long 類型的數據在序列化的時候會轉成 String .setLongSerializationPolicy(LongSerializationPolicy.STRING) //設置 serializeNulls = true .serializeNulls() //設置 prettyPrinting = true .setPrettyPrinting() //設置 generateNonExecutableJson = true .generateNonExecutableJson() //設置 lenient = true .setLenient() //設置 escapeHtmlChars = false .disableHtmlEscaping() //設置 serializeSpecialFloatingPointValues = true .serializeSpecialFloatingPointValues() //建立解析器對象 .create();
在上述設置中,有一大塊是關於排除器 excluder 的設置。excluder 的實現邏輯依賴 ExclusionStrategy 的自定義實現類,追蹤一下 ExclusionStrategy 接口:
//實現 public interface ExclusionStrategy { //設置忽略的變量,須要傳入 FieldAttributes //FieldAttributes 是在 Gson 中定義的 Field 的包裝類 public boolean shouldSkipField(FieldAttributes f); //設置要忽略的 class public boolean shouldSkipClass(Class<?> clazz); }
fieldNamingPolicy 則須要 FieldNamingStrategy 的自定義實現類,追蹤一下 FieldNamingStrategy 接口:
public interface FieldNamingStrategy { //在這個方法中實現自定義的命名規則 public String translateName(Field f); }
FieldNamingPolicy 是一個實現了 FieldNamingStrategy 接口的枚舉類,其中實現了多套 translateName(...) 方法可供選擇。
在 Gson 中封裝了不一樣類型的讀寫的業務組裝類是各個 TypeAdapter(適配器),這裏先來關注一下其具體實現。
先來看一下 TypeAdapterFactory 接口:
public interface TypeAdapterFactory { //只有一個方法,用於根據解析器和變量類型來建立 TypeAdapter <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type); }
再來看一下 TypeAdapter 抽象類:
public abstract class TypeAdapter<T> { //寫入方法,主要的指揮 JsonWriter 進行業務處理 public abstract void write(JsonWriter out, T value) throws IOException; //讀取方法,主要是指揮 JsonReader 進行業務操做 public abstract T read(JsonReader in) throws IOException; //該抽象類中還提供了其它的方法,在此例中沒有用到,暫時忽略 }
關注一下下列這行代碼:
factories.add(TypeAdapters.STRING_FACTORY);
factories 是一個列表,來追蹤一下 TypeAdapters.STRING_FACTORY :
//TypeAdapters.class public static final TypeAdapterFactory STRING_FACTORY = newFactory(String.class, STRING);
先來看一下定義在 TypeAdapters 中的 STRING 變量:
//TypeAdapters.class public static final TypeAdapter<String> STRING = new TypeAdapter<String>() { //此方法用於反序列化時讀取值 @Override public String read(JsonReader in) throws IOException { //in.peek() 方法會獲取到最新的 JsonReader 操做指令,並轉換成下一個要操做的字符類型 //在後面的 part 裏還會提到 JsonToken peek = in.peek(); //讀取到 null if (peek == JsonToken.NULL) { in.nextNull(); return null; } //讀取到 boolean 類型的值 if (peek == JsonToken.BOOLEAN) { return Boolean.toString(in.nextBoolean()); } //除了 null 和 boolean 以外,都視做 String 進行返回 return in.nextString(); } //此方法用於序列化時寫入值 @Override public void write(JsonWriter out, String value) throws IOException { out.value(value); } };
繼續追蹤 newFactory(...) 方法:
//TypeAdapters.class public static <TT> TypeAdapterFactory newFactory(final Class<TT> type, final TypeAdapter<TT> typeAdapter) { return new TypeAdapterFactory() { @SuppressWarnings("unchecked") @Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) { //typeToken.getRawType() 會獲取到這個 TypeToken 所須要的 return typeToken.getRawType() == type ? (TypeAdapter<T>) typeAdapter : null; } //常規的從新 toString() 方法 @Override public String toString() { return "Factory[type=" + type.getName() + ",adapter=" + typeAdapter + "]"; } }; }
從這裏能夠看出,TypeAdapterFactory 本質上只是 TypeAdapter 的包裝類,只是作一個類型的斷定工做,若是斷定爲相同,就會返回傳入的 TypeAdapter。
通常的類型的 TypeAdpter 的操做邏輯都比較相似,不贅述了。
對於通常的自定義類,好比使用者自定義的 java bean 等,並不是 jdk 自帶的基本數據類型,就都須要 ReflectiveTypeAdapter 來進行解析。
先來看一下 ReflectiveTypeAdapterFactory 的 create() 方法:
//ReflectiveTypeAdapterFactory.class public <T> TypeAdapter<T> create(Gson gson, final TypeToken<T> type) { Class<? super T> raw = type.getRawType(); //要確保 type 中獲取出來的 class 的類型是 Object 的子類 //若是不是的話就表明這是基本類型,基本類型的解析不該該使用該適配器 //因此返回 null if (!Object.class.isAssignableFrom(raw)) { return null; } //constructor 用於反射建立對象 ObjectConstructor<T> constructor = constructorConstructor.get(type); //Adapter 是 ReflectiveTypeAdapterFactory 的靜態內部類,繼承了 TypeAdapter return new Adapter<T>(constructor, getBoundFields(gson, type, raw)); }
來繼續追蹤一下 Adapter 的主要方法:
public static final class Adapter<T> extends TypeAdapter<T> { //此處 read(...) 和 write(...) 的代碼比較相似 //主要步驟是經過反射建立出對象,並抓取其全部的變量,逐個存入 public T read(JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull(); return null; } //調用構造器反射建立出對象 T instance = constructor.construct(); //如下代碼是 Gson 讀出字符串中的部分,並用反射填入到對象中的過程 try { in.beginObject(); while (in.hasNext()) { String name = in.nextName(); //BoundField 是 Gson 對 jdk 中的 Field 類的加強 BoundField field = boundFields.get(name); 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; } public void write(JsonWriter out, T value) throws IOException { if (value == null) { out.nullValue(); return; } out.beginObject(); //如下是 Gson 從對象中獲取到數據並寫成字符串的過程 try { for (BoundField boundField : boundFields.values()) { if (boundField.writeField(value)) { out.name(boundField.name); boundField.write(out, value); } } } catch (IllegalAccessException e) { throw new AssertionError(e); } out.endObject(); } }
具體的步驟實際上是對 java 反射的深度定製化應用,不展開了。
以上過程在 JsonReader 和 JsonWriter 的應用中會有相似展開。至於 JsonReader 和 JsonWriter 會在後續進行追蹤。