Gson與Kotlin碰撞出一個(gè)不安全的操作

原因是我們Person沒有提供默認(rèn)的構(gòu)造方法,Gson在沒有找到默認(rèn)構(gòu)造方法時(shí),它就直接通過Unsafe的方法,繞過了構(gòu)造方法,直接構(gòu)建了一個(gè)對象。

到這里,我們收獲了:

Gson是如何構(gòu)建對象的?

我們在寫需要Gson轉(zhuǎn)化為對象的類的時(shí)候,一定要記得有默認(rèn)的構(gòu)造方法,否則雖然不報(bào)錯(cuò),但是很不安全!

我們了解到了還有這種Unsafe黑科技的方式構(gòu)造對象。

4.1、使用 data class 沒有設(shè)置無參構(gòu)造函數(shù)

在 Kotlin 中,不需要自己動(dòng)手去寫一個(gè) JavaBean,可以直接使用 DataClass,使用 DataClass 編譯器會默默地幫我們生成一些函數(shù)。例如:

data class Person(var name: String, var age: Int) {}

這個(gè)Bean是用于接收服務(wù)器數(shù)據(jù),通過Gson轉(zhuǎn)化為對象的。例如:

val gson = Gson() val person = gson.fromJson<Person>("{"age":"12"}", Person::class.java) println(person.name)

我們傳遞了一個(gè)json字符串,但是沒有包含key為name的值,并且注意:

在Person中name的類型是String,也就是說是不允許name=null的

輸出結(jié)果:

null

是不是有些奇怪,感覺意外繞過了Kotlin的空類型檢查。那么是什么原因?qū)е碌哪兀?/p>

原因是:Person在被轉(zhuǎn)Java代碼時(shí),只會生成一個(gè)包含兩個(gè)參數(shù)的構(gòu)造方法,沒有提供默認(rèn)的構(gòu)造方法。Gson在通過反射創(chuàng)建對象時(shí),會優(yōu)先嘗試獲取無參構(gòu)造函數(shù)。如果沒有找到無參構(gòu)造函數(shù)時(shí),它就直接通過Unsafe的方法,繞過了構(gòu)造方法,直接構(gòu)建了一個(gè)對象。

因此我們在使用 data class,在遇到上面類似需求的時(shí)候,最好提供一個(gè)無參構(gòu)造方法。

data class GsonDataTest(val name: String, val gender: String) {

constructor(): this(name = "",gender = "")

override fun toString(): String {

return "GsonDataTest(name='$name', gender='$gender')"

}

}

var data:String? = null

var testData = Gson().fromJson<GsonDataTest>(data, GsonDataTest::class.java)

DebugLog.d("aaaaaa", "$testData")

data = ""

testData = Gson().fromJson<GsonDataTest>(data, GsonDataTest::class.java)

DebugLog.d("aaaaaa", "$testData")

data = "{\"name\":\"aa\"}"

testData = Gson().fromJson<GsonDataTest>(data, GsonDataTest::class.java)

DebugLog.d("aaaaaa", "$testData")

data = "{\"name\":\"aa\", \"gender\":\"aa\"}"

testData = Gson().fromJson<GsonDataTest>(data, GsonDataTest::class.java)

DebugLog.d("aaaaaa", "$testData")
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容