Gson反序列化原理
原理簡(jiǎn)述
gson反序列化主要分為兩個(gè)過程:
對(duì)象的創(chuàng)建
ConstructorConstructor.get
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 @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); } }; } // 獲取無參構(gòu)造函數(shù) ObjectConstructor<T> defaultConstructor = newDefaultConstructor(rawType); if (defaultConstructor != null) { return defaultConstructor; } // 獲取List<T>,Map<T>等構(gòu)造函數(shù),對(duì)于List,Map的情況 ObjectConstructor<T> defaultImplementation = newDefaultImplementationConstructor(type, rawType); if (defaultImplementation != null) { return defaultImplementation; } // unSafe構(gòu)造出對(duì)象,不調(diào)用任何的構(gòu)造函數(shù) // finally try unsafe return newUnsafeAllocator(type, rawType); }ConstructorConstructor.newDefaultConstructor
private <T> ObjectConstructor<T> newDefaultConstructor(Class<? super T> rawType) { try { // 獲取無參構(gòu)造函數(shù) final Constructor<? super T> constructor = rawType.getDeclaredConstructor(); if (!constructor.isAccessible()) { accessor.makeAccessible(constructor); }ConstructorConstructor.newUnsafeAllocator
private <T> ObjectConstructor<T> newUnsafeAllocator( final Type type, final Class<? super T> rawType) { return new ObjectConstructor<T>() { private final UnsafeAllocator unsafeAllocator = UnsafeAllocator.create(); @SuppressWarnings("unchecked") @Override public T construct() { try { // Object newInstance = unsafeAllocator.newInstance(rawType); return (T) newInstance; } catch (Exception e) { throw new RuntimeException(("Unable to invoke no-args constructor for " + type + ". " + "Registering an InstanceCreator with Gson for this type may fix this problem."), e); } } }; }結(jié)論
kotlin構(gòu)造函數(shù)默認(rèn)參數(shù)和無參構(gòu)造函數(shù)的關(guān)系
參數(shù)里面存在沒有默認(rèn)值的情況
kotlin代碼
class User(val id: Int, val name: String = "sss") { init { println("init") }}反編譯的Java代碼
public final class User { private final int id; @NotNull private final String name; public User(int id, @NotNull String name) { Intrinsics.checkParameterIsNotNull(name, "name"); super(); this.id = id; this.name = name; String var3 = "init"; System.out.println(var3); } // $FF: synthetic method public User(int var1, String var2, int var3, DefaultConstructorMarker var4) { if ((var3 & 2) != 0) { var2 = ""; } this(var1, var2); }}gson反序列化輸出
代碼:
@Test fun testJson() { val user = Gson().fromJson("{}", User::class.java) print(user.name) }輸出:不符合預(yù)期(我們聲明的非空的name實(shí)際結(jié)果是null)
null
Process finished with exit code 0
參數(shù)都包含默認(rèn)參數(shù)的情況
kotlin代碼
class User(val id: Int=1, val name: String = "sss") { init { println("init") }}反編譯Java代碼
public final class User { private final int id; @NotNull private final String name; public User(int id, @NotNull String name) { Intrinsics.checkParameterIsNotNull(name, "name"); super(); this.id = id; this.name = name; String var3 = "init"; System.out.println(var3); } // $FF: synthetic method public User(int var1, String var2, int var3, DefaultConstructorMarker var4) { if ((var3 & 1) != 0) { var1 = 1; } if ((var3 & 2) != 0) { var2 = ""; } this(var1, var2); } // 無參構(gòu)造函數(shù) public User() { this(0, (String)null, 3, (DefaultConstructorMarker)null); }}gson反序列化輸出
代碼:
@Test fun testJson() { val user = Gson().fromJson("{}", User::class.java) print(user.name) }輸出:符合預(yù)期
init
sss
Process finished with exit code 0
Best Practice
Practice1
class User(val id: Int=1 , val name: String = "sss") { init { println("init") }}Practice2
回歸到Java的寫法即可
class User { val id: Int = 1 val name: String = "sss" init { println("init") }}總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)VeVb武林網(wǎng)的支持。
新聞熱點(diǎn)
疑難解答
圖片精選