亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > 綜合 > 正文

kotlin gson反序列化默認值失效深入講解

2024-07-21 23:03:51
字體:
來源:轉載
供稿:網友

Gson反序列化原理

原理簡述

gson反序列化主要分為兩個過程:

  • 根據TypeToken創建出對象
  • 根據json字符串解析數據,對對象屬性賦值

對象的創建

ConstructorConstructor.get

  • 先嘗試獲取無參構造函數
  • 失敗則嘗試List、Map等情況的構造函數
  • 最后使用Unsafe.newInstance兜底(此兜底不會調用構造函數,導致所有對象初始化代碼不會調用)
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);  }  }; } // 獲取無參構造函數 ObjectConstructor<T> defaultConstructor = newDefaultConstructor(rawType); if (defaultConstructor != null) {  return defaultConstructor; } // 獲取List<T>,Map<T>等構造函數,對于List,Map的情況 ObjectConstructor<T> defaultImplementation = newDefaultImplementationConstructor(type, rawType); if (defaultImplementation != null) {  return defaultImplementation; } // unSafe構造出對象,不調用任何的構造函數 // finally try unsafe return newUnsafeAllocator(type, rawType); }

ConstructorConstructor.newDefaultConstructor

  • 調用Class.getDeclaredConstructor獲取無參構造函數
private <T> ObjectConstructor<T> newDefaultConstructor(Class<? super T> rawType) { try {  // 獲取無參構造函數  final Constructor<? super T> constructor = rawType.getDeclaredConstructor();  if (!constructor.isAccessible()) {  accessor.makeAccessible(constructor);  }

ConstructorConstructor.newUnsafeAllocator

  • 調用UnSafe.newInstance創建出對象
  • 不會調用構造函數,因此所有的初始化的代碼都不會被調用
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);  }  } }; }

結論

  • Gson反序列要工作正常,使結果符合預期的話,要求類必須有一個無參構造函數

kotlin構造函數默認參數和無參構造函數的關系

參數里面存在沒有默認值的情況

kotlin代碼

  • id沒有默認值
class User(val id: Int, val name: String = "sss") { init {  println("init") }}

反編譯的Java代碼

  • 包含兩個構造函數,一個是我們聲明的全參數構造函數,另一個是kotlin生成的輔助構造函數
  • 不包含無參構造函數
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) }

輸出:不符合預期(我們聲明的非空的name實際結果是null)

null
Process finished with exit code 0

參數都包含默認參數的情況

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); } // 無參構造函數 public User() {  this(0, (String)null, 3, (DefaultConstructorMarker)null); }}

gson反序列化輸出

代碼:

 @Test fun testJson() {  val user = Gson().fromJson("{}", User::class.java)  print(user.name) }

輸出:符合預期

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") }}

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到kotlin教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久精品免费播放| 欧美日韩另类视频| 欧美性猛交xxxx免费看漫画| 亚洲精品国产拍免费91在线| 久久97精品久久久久久久不卡| 亚洲精品久久久久久久久久久| 亚洲大尺度美女在线| 久久精品免费播放| 国产97在线观看| 日本一欧美一欧美一亚洲视频| 国产精品午夜视频| 欧美一级高清免费播放| 日韩欧美国产一区二区| 日本高清不卡的在线| 色狠狠久久aa北条麻妃| 2019中文字幕免费视频| 国产精品一区二区三区久久久| 亚洲国产成人爱av在线播放| 美乳少妇欧美精品| 亚洲国产精品成人av| 97超级碰在线看视频免费在线看| 国产一区二区色| 国产成人欧美在线观看| 97超级碰碰碰久久久| 亚洲国产精品yw在线观看| 欧美成人精品在线播放| 日韩欧美精品在线观看| 一本色道久久88综合亚洲精品ⅰ| 亚洲欧美制服另类日韩| 欧美激情一区二区三区久久久| 69久久夜色精品国产7777| 亚洲视频在线观看视频| 国产精品久久久久久久7电影| 日韩电视剧在线观看免费网站| 亚洲精品自拍第一页| 成人精品一区二区三区电影黑人| 亚洲综合av影视| 日本三级韩国三级久久| 国产精品久久久久999| 国内外成人免费激情在线视频| 国内精品美女av在线播放| 欧美—级a级欧美特级ar全黄| 亚洲欧美变态国产另类| 久久久久久久久久久网站| 国产精品99久久久久久久久久久久| 国产成人精品久久亚洲高清不卡| 全球成人中文在线| 欧美资源在线观看| 日本精品久久中文字幕佐佐木| 精品国内亚洲在观看18黄| 欧美体内谢she精2性欧美| 欧美午夜精品在线| 精品国偷自产在线视频| 国产一区二区日韩精品欧美精品| 一级做a爰片久久毛片美女图片| 欧美电影免费观看网站| 日韩风俗一区 二区| 亚洲护士老师的毛茸茸最新章节| 久久久久久免费精品| 色哟哟网站入口亚洲精品| 日本成人激情视频| 国产91在线高潮白浆在线观看| 亚洲欧美日韩国产成人| 一色桃子一区二区| 亚洲人成欧美中文字幕| 97视频在线观看成人| 欧美成人在线免费视频| 久久久久久久久久久人体| 亚洲日本欧美日韩高观看| 国产亚洲美女久久| 国产91ⅴ在线精品免费观看| 亚洲一区二区久久久久久久| 九九精品视频在线观看| 国产免费观看久久黄| 91精品久久久久久久久久| 一区二区欧美亚洲| 青草热久免费精品视频| 日韩免费观看在线观看| 亚洲欧美日韩爽爽影院| 欧美插天视频在线播放| 在线观看欧美日韩国产| 91久久精品久久国产性色也91| 欧美午夜丰满在线18影院| 成人免费观看a| 欧美最猛性xxxx| 一区二区在线视频播放| 26uuu亚洲国产精品| 欧美日韩中文字幕综合视频| 国产精品第1页| 亚洲精品成人网| 国产日韩专区在线| 久久亚洲欧美日韩精品专区| 日本国产一区二区三区| 性日韩欧美在线视频| 欧美日韩精品在线播放| 欧美日韩在线观看视频| 欧美日韩亚洲网| 欧美国产乱视频| 亚洲一区二区免费在线| 夜夜嗨av色综合久久久综合网| 亚洲色图狂野欧美| 国产精品亚洲片夜色在线| 亚洲成人久久网| 欧美日韩中文字幕日韩欧美| 亚洲va久久久噜噜噜久久天堂| 日韩女优在线播放| 91欧美激情另类亚洲| 青青草精品毛片| 亚洲免费电影在线观看| 成人久久一区二区三区| 91久久久久久| 国产精品久久av| 91久久精品国产| 久久人人爽人人爽爽久久| 97av在线视频免费播放| 色悠悠久久久久| 一本色道久久88综合亚洲精品ⅰ| 不卡伊人av在线播放| 精品亚洲男同gayvideo网站| 欧美视频专区一二在线观看| 国产精品白嫩初高中害羞小美女| 欧美在线视频一区二区| 国产97人人超碰caoprom| 日韩久久免费电影| www高清在线视频日韩欧美| 亚洲人成免费电影| 日韩精品免费在线视频观看| 国产精品日韩在线| 亚洲另类激情图| 久久久精品在线观看| 91丝袜美腿美女视频网站| 在线播放精品一区二区三区| 日韩av有码在线| 久久九九国产精品怡红院| 亚洲欧洲自拍偷拍| 日本精品免费观看| 精品视频中文字幕| 亚洲欧美综合图区| 91精品国产自产在线老师啪| 91精品国产综合久久久久久蜜臀| 亚洲第一天堂无码专区| 中文字幕精品久久久久| 欧美激情日韩图片| 26uuu另类亚洲欧美日本老年| 日韩国产一区三区| 欧美精品videossex性护士| 亚洲精品视频免费在线观看| 国产成人在线亚洲欧美| 2019亚洲男人天堂| 91国内产香蕉| 7777kkkk成人观看| 成人性生交大片免费观看嘿嘿视频| 国产一区二区激情| 91精品免费久久久久久久久| 欧美在线www| 日韩欧美国产骚| 2019中文在线观看| 欧美日韩国产一区二区三区| 在线视频免费一区二区| 精品国产网站地址| 欧美精品xxx| 中文字幕综合在线| 国产成人精品一区| 成人高清视频观看www|