Kotlin Json库问题总结(Gson以及Moshi的坑),阿里巴巴android开发规范

本文总结了在处理Kotlin JSON序列化时遇到的问题,特别是Gson和Moshi库中关于null值的处理。通过自定义解析器,解决了Gson中null值覆盖默认值以及Moshi中非空字段null值抛异常的问题。同时提供了GsonDefaultAdapterFactory和MoshiDefaultAdapterFactory的示例代码,展示如何替换null值为默认值。
摘要由CSDN通过智能技术生成

// …1110 & …1101 = …1100,次低位0表示第二个默认字段在json中存在,不需要赋默认,以此类推
mask0 = mask0 and 0xfffffffd.toInt()
}
2 -> age = intAdapter.fromJson(reader) ?: throw Util.unexpectedNull(“age”, “age”, reader)
-1 -> {
// Unknown name, skip it.
reader.skipName()
reader.skipValue()
}
}
}
reader.endObject()
if (mask0 == 0xfffffffc.toInt()) {
// 如果所有默认字段都存在于json中,则忽略默认值直接调用构造函数赋值成json中的值
return DefaultPart(
name = name as String,
gender = gender as String,
// age字段非空,如果在json中没有对应key则抛异常
age = age ?: throw Util.missingProperty(“age”, “age”, reader)
)
} else {
// 如果有默认值的字段在Json中不存在,则传入flag反射调用synthetic构造函数,填充默认值
@Suppress(“UNCHECKED_CAST”)
val localConstructor: Constructor = this.constructorRef ?:
DefaultPart::class.java.getDeclaredConstructor(String::class.java, String::class.java,
Int::class.javaPrimitiveType, Int::class.javaPrimitiveType,
Util.DEFAULT_CONSTRUCTOR_MARKER).also { this.constructorRef = it }
return localConstructor.newInstance(
name,
gender,
age ?: throw Util.missingProperty(“age”, “age”, reader),
mask0,
/* DefaultConstructorMarker */ null
)
}
}
}

做的事情其实也很简单,代码中我写了注释

  1. 用一个int记录(字段超过32个使用多个int)默认值字段在将要解析的json中是否存在,从最低位到最高位依次记录第一个到最后一个默认值字段在json中是否有key,0表示存在,1表示不存在
  2. 判断是否所有默认字段在json中都有值,若为true则不用管默认值,直接使用json字段生成实例,若为false则反射调用(synthetic构造器只能够反射调用)synthetic构造器实例化对象,synthetic构造器会根据标志位为默认值字段赋值

一言蔽之,Moshi通过遵循Kotlin的机制做到了兼容。

解决方案

分析了这么多,避免默认值无效的方法已经显而易见了

  1. 定义类时所有字段都给一个默认值,这样gson就可以正常工作
  2. 使用Moshi库

其他问题,Json中value为null的情况

正常情况下后端返回的Json数据中只应该存在Object类型字段为null的情况,但是现实很骨感,不乏String类型/list类型丢过来也是null的情况。

  • 在Java中,null value会覆盖掉默认值,使用时get方法中判空就可以了。
  • 但是在Kotlin中,如果该字段声明为非空类型,使用gso
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值