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
}