关于kotlin实体对象序列化时Is开头的属性名所产生的问题)

3 篇文章 0 订阅
1 篇文章 0 订阅

关于实体对象的序列化时Is开头的属性所产生的问题

摘要

今天在开发的时候遇到了一个奇葩问题,记录一下,防止以后遇到,也让一些遇到的小伙伴有点思路;

使用的第三方包

用了FastJson作为Json解析工具,网络三件套
ps:感觉涉及到序列话都会有问题

情景

原有的项目是用Java写的,近期在修改部分文件转为Kotlin,不得不说,kotlin的data class是真的香,至少目前很香,虽说遇到了很多坑,当然不是本文的重点,就不谈了。
好了,继续说,我有一个data class的实体类,
例如:我有一个类,Student

// 一个Kotlin 版本的 Student诞生了
@Parcelize
data class Student(var name: String? = null,
                   var isLocal: Boolean? = false,//类型::Boolean,is开头,getter方法‘重写为’ getIs...
                   var isBoy: Boolean? = false,//类型::Boolean, is开头,getter方法默认生成  is...
                   var isFoolish: Int? = -1,//类型::Int,is开头,getter方法‘重写为’ getIs...
                   var isLike: String? = null//类型::String,is开头,getter方法默认生成  is...
) : Parcelable {
    fun getIsLocal(): Boolean? {
        return isLocal
    }

    fun getIsFoolish(): Int? {
        return isFoolish
    }
}

重点关注is开头的几个属性,和对应的Getter方法,接下来我们进行序列化和反序列化,其实就是用创建个对象,用Fastjson进行解析转化为文本,如下:

class Test {
    //输入co 回车
    companion object {
        //输入maino  回车就出现mian方法了,慎用,容易上瘾
        @JvmStatic
        fun main(args: Array<String>) {
            val student = Student()
            student.name = "张三"  //永远的张三
            student.isLocal = true
            student.isBoy = false
            student.isFoolish = 1
            student.isLike = "跳皮筋"
            val jsonStr = JSONObject.toJSONString(student)
            println("实体转JsonString后::$jsonStr")
            val json = JSONObject.parse(jsonStr)
            println("将Json字符串转化为JSON$json.toString()")
            val newStudent = JSONObject.parseObject(jsonStr, Student::class.java)
            println("将Json字符串转化为实体类$newStudent.toString()")
            println("列举反射成员属性和方法::")
            newStudent::class.members.forEach { println(it.toString()) }
        }
    }
}

打印结果:

实体转JsonString后::{ "boy":false, "isFoolish":1, "isLocal":true, "local":true, "name":"张三" }
将Json字符串转化为JSON{ "name":"张三", "isFoolish":1, "boy":false, "local":true, "isLocal":true }.toString()
将Json字符串转化为实体类Student(name=张三, isLocal=true, isBoy=false, isFoolish=1, isLike=null).toString()
枚举反射成员属性和方法::
var Student.isBoy: kotlin.Boolean?
var Student.isFoolish: kotlin.Int?
var Student.isLike: kotlin.String?
var Student.isLocal: kotlin.Boolean?
...
fun Student.getIsFoolish(): kotlin.Int?
fun Student.getIsLocal(): kotlin.Boolean?

序列化后导致以下情况:

  1. 不管是否Boolean类型,用data class自动生成的is...方法消失了
  2. 不管是否Boolean类型,通过反编码为Java后,is开头字段的getter方法会变为is…方法
  3. 不管是否Boolean类型,手动“重写”的getter则会不会消失,能通过反射获取
  4. 不管是否Boolean类型,手动“重写”的getter方法也是正常显示

差点重装Android Studio

因上次遇到过一次Android studio 的缓存问题,在序列化接口入参的时候一直获取不到某个值,甚至一度认为是Android Studio出的问题,哈哈哈哈,结果不是,真尴尬。

解决方案

经过研究测试,总结了三种方案:

  1. 让后台修改字段名,不用这个了(就是这么霸气,你要么别问我要,问我要就必须按我的来) ,不推荐
  2. 上面代码也看到了,手动重写getter,详见上述代码
  3. 本地修改字段名成,并且设置Json序列化的命名,如下修改实体类:
// 一个Kotlin 版本的 Student诞生了
@Parcelize
data class Student(var name: String? = null,
                   @JSONField(name="isLocal")
                   var abc: Boolean? = false,//类型::Boolean,is开头,getter方法‘重写为’ getIs...
                   @JSONField(name="isLocal")
                   var boy1213: Boolean? = false,//类型::Boolean, is开头,getter方法默认生成  is...
                   @JSONField(name="isLocal")
                   var foolishAAAA: Int? = -1,//类型::Int,is开头,getter方法‘重写为’ getIs...
                   @JSONField(name="isLocal")
                   var likeAbc: String? = null//类型::String,is开头,getter方法默认生成  is...
) : Parcelable

名字可以随便去,最终序列化后的名字就是name后面所对应的值。

总结

第一次正儿八经写博客,还有待研究学习和提升,下回有问题见。
大佬给点赞鼓鼓力。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值