kotlin 泛型的高級特性

1.泛型實化

前言:java和kotlin都是類型擦除機制,泛型只是對於編譯器的類型的約束,運行期是識別不出來我們代碼中指定的泛型類型的。

所以肯定實現不了 a is T 或者 T::class.java

泛型實化:利用內聯函數和reified關鍵字可以進行泛型實化

例如:inline fun <reified T> getGenricType() = T::class.java

泛型實化的應用:

//用到了內聯函數實化,擴展函數,高階函數
inline fun <reified T> startActivity(context:Context,block:Intent.() -> Unit){
    val intent = Intent(context,T::class.java)
    intent.block()
    context.startActivity()
}

//用到了lambda表達式
startActivity<TestActivity>(this){
    putExtra("param1","data")
    putExtra("param2",123)
}

2.泛型的協變

java中不允許List<Student>是List<Person>的子類,原因如下:

class SimpleData<T> {
    
    private var data:T? = null

    fun set(t:T?){
        data = T
    }

    fun get():T = data
}

val student = Student()
val data = SimpleData<Student>()
data.set(student)
val teacher = Teacher()
data.set(teacher)
val studentData = data.get()//此處就存在隱患,不知道是Student還是Teacher

協變:假如A是B的子類型,則MyClass<A>也是MyClass<B>的子類型

實現如下:利用out關鍵字

class SimpleData<out T>(val data:T) {

    fun get():T = data

}

3.泛型的逆變

如果A是B的子類型,則MyClass<B>是MyClass<A>的子類型

interface Transformer<T> {
    fun transform(t:T):String
}

fun main(){
    val trans = object : Transtormer<Person> {
        override fun transform(t:Person):String = "${t.name}${t.age}"
    }
    handleTransformer(trans)//會報錯,因爲Transtormer<Person>不是Transtormer<Student>子類
}

fun handleTransformer(t:Transtormer<Student>){
    val student = Student()
    val result = t.transform(student)
}

//逆變修改如下
interface Transformer<in T> {
    fun transform(): @UnsafeVariance T
}

fun main(){
    val trans = object : Transtormer<Person> {
        override Teacher()
    }
    handleTransformer(trans)//通過編譯,但是寫法不對
}

fun handleTransformer(t:Transtormer<Student>){
    val student = Student()
    val result = t.transform(student)
}

具體源碼例子,Comparable用於對比兩個對象大小的接口

interface Comparable<in T>{
    operator fun comparaTo(other:T):Int
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章