今天在 Java convert to Kotlin 的工程中
想到了這個問題
我們一定常常遇到 Java 泛型的寫法吧?
比如最常見的 ArrayList<T>
或是在 method 中也會出現
如 Gson 的 fromJson() 原碼
public <T> T fromJson(String json, Class<T> classOfT)
throws JsonSyntaxException {
Object object = fromJson(json, (Type) classOfT);
return Primitives.wrap(classOfT).cast(object);
}
那 Kotlin 中的泛型如何表現呢?
就以 Gson 做為例子好了
在傳輸資料時,Gson 想必是大家常用的工具吧?
假設一個情境,我登入了
然後把 UserData 存進 SharedPerferences 之中
其中 Object、String 之間的相互轉換就用 Gson 來做
然後現在我們要取 UserData 出來了
會用到下面的 Java method
public <T> T getObject(String keyName, Class<T> clazz) {
return new Gson().fromJson(getString(keyName), clazz);
}
可以看到我們利用泛型來決定 return 的 class 是什麼
這很好理解
那到了 Kotlin 我們要如何寫出一樣的功能呢?
Kotlin 一樣有泛型,位置是在 fun name 前面
寫起來像這樣
fun <T>getObject(keyName: String):T
= Gson().fromJson(getString(keyName),T::class.java)
但這樣寫會發生錯誤
Cannot use 'T' reified type parameter.
為什麼呢?
因為 T 是虛的,他沒辦法具現化
這時候就要提到兩個關鍵字了 inline & reified
說到 inline 就要提到 C 語言
因為這是從 C 搬過來的概念
加入 inline 的 fun 就叫做「內聯函數」
它可以節省每次調用函數帶來的額外時間開支
回正題
reified 要搭配 inline 才可以使用
否則會報錯
Only type parameters of inline function can be reified.
加入之後會變成這樣
inline fun <reified T>getObject(keyName: String):T
= Gson().fromJson(getString(keyName),T::class.java)
這麼一來就可以使用了
調用方式如下
getObject<UserData>(KEY_USER_DATA)
資料來源:
https://kotlinlang.org/docs/reference/inline-functions.html
https://zh.wikipedia.org/wiki/%E5%86%85%E8%81%94%E5%87%BD%E6%95%B0