前言
最近開(kāi)始重構(gòu),Javabean也想全部替換成kotlin的data class,可data class使用有諸多限制,并沒(méi)有Javabean使用的那么隨心所欲。在此也記錄下遇到的坑吧。
坑1:沒(méi)有無(wú)參構(gòu)造器
data class 沒(méi)有無(wú)參構(gòu)造器,創(chuàng)建此類至少要有一個(gè)參數(shù)。造成的不變就在于如果想手動(dòng)創(chuàng)建數(shù)據(jù),就要將所有的參數(shù)都賦值一遍。沒(méi)有JavaBean直接通過(guò)無(wú)參構(gòu)造器創(chuàng)建對(duì)象來(lái)的方便。
解決辦法:雖然網(wǎng)上有很多的方式,包括使用什么插件,引入什么依賴,但有眾多的限制,依然是不能隨意的創(chuàng)建無(wú)參的data class實(shí)體類。如果使用data class的話,就不用想無(wú)參構(gòu)造器創(chuàng)建了,可以使用替代的方式來(lái)減少繁瑣。比如,data class 有 copy()
方法,可以直接copy出一個(gè)與原對(duì)象相同數(shù)據(jù)的對(duì)象,也可以傳遞某些參數(shù)來(lái)動(dòng)態(tài)更改其數(shù)據(jù)。
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中,不存在什么非空字段,無(wú)非就是數(shù)據(jù)沒(méi)有返回,調(diào)用的時(shí)候是空而已,只需要在代碼中判斷非空就行。而使用data class就要在書(shū)寫(xiě)的時(shí)候加非空判斷。比如:
data class DemoBean(val name: String, val sex: String)
這樣寫(xiě),通過(guò)json轉(zhuǎn)換來(lái)的字段必須包含 name
和 sex
,值可以為空,但必須得有這倆字段,否則轉(zhuǎn)換不過(guò)來(lái)。
比如json為:
{"name":"11","sex","男"}
這樣可以直接轉(zhuǎn)換,但如果json是
{"name":"222"} 或者 {"sex","女"}
這樣有缺省字段的情況下是無(wú)法轉(zhuǎn)換成data class的。
解決辦法1:所有字段都加非空判斷?
將data class改成這樣
data class DemoBean(val name: String?, val sex: String?)
允許字段為空,json缺省狀態(tài)下依然可以使用,但帶來(lái)的不便就是使用字段的時(shí)候都需要加判空標(biāo)識(shí)符?
,其實(shí)也挺麻煩的。
解決辦法2:約束api數(shù)據(jù)返回
代碼層次上無(wú)法像javabean那么隨心所欲的情況下,就直接從源頭上解決問(wèn)題吧。跟后臺(tái)定好協(xié)議,文檔上有的字段,必須全部返回,即便沒(méi)有數(shù)據(jù),也要返回空字段。這樣帶來(lái)的問(wèn)題就是后續(xù)api接口數(shù)據(jù)字段只能增不能減,擴(kuò)展性稍微差點(diǎn)。不過(guò)以我這么多年的工作經(jīng)驗(yàn)來(lái)看,減字段優(yōu)化接口還不如重新寫(xiě)一個(gè)接口更方便,減少線上出問(wèn)題的風(fēng)險(xiǎn)。
坑3 復(fù)用性問(wèn)題
從坑2里延伸來(lái)的問(wèn)題,如果幾個(gè)接口返回的數(shù)據(jù)很類似,有公共數(shù)據(jù)字段,各自還有各自獨(dú)立的屬性字段,在javabean中可以抽離出公共字段到基類,然后各自繼承基類就可以實(shí)現(xiàn)復(fù)用。
但kotlin的data class也想類似javabean那種抽離出公共字段到一個(gè)data class,子類再繼承使用就會(huì)出很大的問(wèn)題。雖然data class可以繼承,但是可繼承的類有限,可以繼承abstract
修飾的抽象類,可以繼承sealed
修飾的密封類,像同為data class的數(shù)據(jù)類以及普通的不修飾的類,都無(wú)法繼承。
解決辦法1:不復(fù)用(廢話),全字段寫(xiě)到對(duì)應(yīng)的data class中。
解決辦法2:放棄data class,寫(xiě)普通的kotlin類來(lái)封裝數(shù)據(jù),可以跟javabean一樣,解決復(fù)用問(wèn)題
解決辦法3:使用abstract
修飾的抽象類來(lái)封裝公共數(shù)據(jù)字段,各自data class繼承此抽象類。
解決辦法4:把所有的字段都放到同一個(gè)data class中,其中公共字段不需要添加非空判斷,其余獨(dú)立字段均加上非空判斷,可以正常解析使用。
坑4 kotlin的反射依賴
項(xiàng)目中使用的fastJson,需要配合kotlin反射依賴才能順利解析。
"org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
匹配好自己的kotlin版本即可。
添加混淆配置:
-keepattributes *Annotation*
-keep class kotlin.** { *; }
-keep class org.jetbrains.** { *; }
必加的依賴,否則一堆問(wèn)題。
終極解決方案
出現(xiàn)上述問(wèn)題的主要原因是用了fastjson,但如果換成Gson,上述的解析方面的問(wèn)題就都不是問(wèn)題了。無(wú)論字段是否缺省,無(wú)論是否配置kt的反射依賴,gson都可以完美的適配data class。少年,不想那么操蛋的配置,就換gson吧。
尾聲
目前遇到這些坑,先記錄下來(lái),等以后還遇到什么問(wèn)題,再補(bǔ)充吧。