時間:Mar 2, 2017
原文鏈接:https://antonioleiva.com/reified-types-kotlin/
對於Java開發者來說,最懊惱的限制之一是,在用泛型時不能夠直接地使用類型。
通常解決方法是以函數參數形式傳遞類,這使得代碼更復雜且缺乏吸引力。
在Kotlin中,多虧有了inline函數(我們已經討論過),我們可以用reified類型使我們能夠在函數內使用它們。
為什么會如此?你會明白的,你會喜歡它的。
Reified 類型
如我早前的論述,以reified修飾類型后,我們就能夠在函數內部使用相關類型了。
重要的是,使用內聯函數后,在其運行地方需要替換代碼來獲得類型。事實上由於Java虛擬機的限制,類型不能使用,而是跳過限制的“詭計”。
引導到一個活動(Activity)
這是最典型的Android應用案例。
在Java中,我們調用startActivity時,我們需要以參數形式指明目的類。
在Kotlin中,我們能夠通過添加類型傳遞給函數來簡化這個操作:
1 inline fun <reified T : Activity> Activity.startActivity() { 2 startActivity(Intent(this, T::class.java)) 3 }
現在,引導一個Activity就可以如此簡單:
1 startActivity<DetailActivity>()
FindView類型轉換
部分Android開發人員使用Java十分有益的方式是用泛型通過變量賦值結果返回對象類型。
在Java中,你可以產生這樣的一個函數:
1 public <T extends View> T findView(Activity activity, int id) { 2 return (T) activity.findViewById(id); 3 }
然后用它返回對象類型:
1 TextView textView = Utils.findView(activity, R.id.welcomeMessage);
在Kotlin中,做法有些類似,但是由於有了擴展函數就更加容易:
1 fun <T : View> Activity.findView(id: Int) = findViewById(id) as T 2 3 val textView = activity.findView<TextView>(R.id.welcomeMessage)
但是,你會發現這種情況,由於沒有訪問T類型,編譯器都不能確定有效類型,所以編譯器會給出警告。
用了reified類型,就可以避免這種情況:
1 inline fun <reified T : View> Activity.findView(id: Int) = findViewById(id) as T
結論
用reified類型,你能夠做一些在Java中不可能實現的事情,甚至可以做一些更安全的函數。
現在,你可以避免將類的類型作為自變量傳遞給你的函數了。
此外,由於有了擴展函數,你能夠在框架(如Android)上創建新函數了。在Android的API中有些部分已經使用這個方法(如startActivity方法)。
如果你要開始用Kotlin開發你自己的APP,我建議你閱讀免費指南和Android開發者的Kotlin書。