Gson反序列化时导致实体类的默认值失效了

一、问题示例

实体类TestBean:

class TestBean implements Serializable{
    String title;
    boolean isShow = true;//这里给isShow设置了默认值,坑点
}

反序列化代码:

new Gson().fromJson("{title:\"标题\"}", TestBean.class);

预计得到的结果:

TestBean.title 值等于 “标题”
TestBean.isShow 值等于 “true

实际得到的结果:

TestBean.title 值等于 “标题”
TestBean.isShow 值等于 “false
二、原理分析

gson反序列化主要分为两个过程:

  • 根据TypeToken创建出对象
  • 根据json字符串解析数据,对对象属性赋值

对象的创建过程如下:

  • 先尝试获取无参构造函数
  • 失败则尝试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);
 }

Gson反序列要工作正常,使结果符合预期的话,要求类必须有一个无参构造函数

二、解决方案

让TestBean实现一个默认构造函数:

class TestBean implements Serializable{
    public TestBean() {
    }

    String title;
    boolean isShow = true;
}

如果是内部类需要设置static才可以

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

互联网小熊猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值