kotlin data class 遇到的问题以及解决方案

kotlin data class相比于JavaBean有诸多的限制,并没有JavaBean使用的那么随心所欲。在此记录下使用data class遇到的问题。

1.没有无参构造器

通过查看字节码我们会发现,data class被编译成了一个final class,而且没有默认的无参构造器。所以创建此类至少要有一个参数,造成的不变就在于如果你想手动创建数据,就得要将所有的参数都赋值一遍,没有JavaBean直接通过无参构造器创建对象来的方便。

解决办法1:在data class 里面所有字段都写上默认值,就可以不传入参数创建类,或者通过具名参数的方式,传入某几个参数创建类。

data class Person(
    var age: Int? = 0,
    var name: String? = "",
    val sex: Boolean? = false
)


 val teacher = Person()
 val student = Person(name = "lyx")

解决办法2:虽然网上有很多的方式,包括使用什么插件,引入什么依赖,但有众多的限制,依然是不能随意的创建无参的data class实体类。如果使用data class的话,就不用想无参构造器创建了,可以使用替代的方式来减少繁琐。比如,data class 有 copy()方法,可以直接copy出一个与原对象相同数据的对象,也可以传递某些参数来动态更改其数据。

val demo = DemoBean("hhh","男")

val copy = demo.copy()
val copy1 = demo.copy(name = "111")
val copy2 = demo.copy(sex = "女")
val copy3 = demo.copy(name = "222", sex = "嬲")


2.非空字段

在JavaBean中,不存在什么非空字段,无非就是数据没有返回,调用的时候是空而已,只需要在代码中判断非空就行。而使用data class就要在书写的时候加非空判断。比如:

data class Person(
    var age: Int,
    var name: String,
    val sex: Boolean
)

这样写,通过json转换来的字段必须包含 age、name 和 sex,值可以为空,但必须得有这三个字段,否则转换不过来。
比如json为:

{"name":"lyx","age":18,"sex",true}

这样可以直接转换。但如果json是

{"name":"lyx"}  或者 {"age":18,"sex",true}

这样有缺省字段的情况下是无法转换成data class的。

解决办法1:所有字段都加非空判断?
将data class改成这样

data class Person(
    var age: Int?,
    var name: String?,
    val sex: Boolean?
)

允许字段为空,json缺省状态下依然可以使用,但带来的不便就是使用字段的时候都需要加判空标识符?,其实也挺麻烦的。


解决办法2:约束api数据返回

代码层次上无法像JavaBean​​​​​​​那么随心所欲的情况下,就直接从源头上解决问题吧。跟后台定好协议,文档上有的字段,必须全部返回,即便没有数据,也要返回空字段。这样带来的问题就是后续api接口数据字段只能增不能减,扩展性稍微差点。不过以我这么多年的工作经验来看,减字段优化接口还不如重新写一个接口更方便,减少线上出问题的风险。

解决方案3:

出现上述问题的主要原因是用了fastjson,但如果换成Gson,上述的解析方面的问题就不是问题了。gson可以完美的适配data class。

3.继承和复用性问题

data class可以继承,但是不能被继承。问题1的时候我们说过,data class被编译成了final class,是不能被继承的。

但是有种很常见的业务场景:比如接口request类有很多公用的参数,但是不同的接口又有其独立的参数。在JavaBean中可以抽离出公共字段到基类,然后各自继承基类就可以实现复用了。data class可以借鉴问题1的解决方法来实现。

open class Person(
    var age: Int? = 0,
    var name: String? = "lyx",
    val sex: Boolean? = false
)

data class Student(val score: Int) : Person()

4.kotlin的反射依赖

如果项目中使用的fastJson,需要配合kotlin反射依赖才能顺利解析。
"org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" 匹配好自己的kotlin版本即可。
添加混淆配置:

-keepattributes *Annotation*
-keep class kotlin.** { *; }
-keep class org.jetbrains.** { *; }

必加的依赖,否则一堆问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值