内容简介:gson反序列化主要分为两个过程:ConstructorConstructor.getConstructorConstructor.newDefaultConstructor
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") } } 复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 行间距失效问题
- 前端实现设置缓存数据定时失效
- 5分钟探究Spring事务失效原因
- Andorid内Aspectj切面失效分析
- Xcode 代码提示失效以及引发的感想
- Firefox 已发布“插件失效”证书修复补丁
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Flash PHP实用开发技术
Steve Webster著、王黎译 / 王黎 / 清华大学出版社 / 2002-3 / 39.00元
本书将介绍服务器端脚本所提供的各种可能的操作方案,帮助读者掌握设计数据库集成程序和高端应用程序的知识。一起来看看 《Flash PHP实用开发技术》 这本书的介绍吧!