泛型
class MyGenericsClass<T> {
fun method(param: T): T {
return param
}
}
val myIntClass = MyGenericsClass<Int>()
val myStringClass = MyGenericsClass<String>()
println(myIntClass.method(26))
println(myStringClass.method("Yang"))
26
Yang
class MyGenericsMethod {
fun <T> method(param: T): T {
return param
}
}
val myIntMethod = MyGenericsMethod()
val myStringMethod = MyGenericsMethod()
println(myIntMethod.method<Int>(26))
println(myStringMethod.method<String>("Yang"))
26
Yang
class MyGenericsProperty<T> {
var property: T? = null
}
val myIntProperty = MyGenericsProperty<Int>().apply { property = 26 }
val myStringProperty = MyGenericsProperty<String>().apply { property = "Yang" }
println(myIntProperty.property)
println(myStringProperty.property)
26
Yang
class MyConstraint {
fun <T : Number?> method(param: T): T = param
fun <T> method(param: T) where T : Number, T : Comparable<T> = param
}
- 泛型约束
out
关键字:协变
out
关键字用于声明一个泛型类型是协变的。这意味着你可以将该泛型类型用于返回值,但不能用于消费(即输入参数)。协变的类型参数可以安全地从子类型转换到父类型。例如,Producer<out T>
表示该类型只能作为生产者,它可以返回 T
或 T
的子类型的对象。协变的核心思想是“只生产,不消费”
in
关键字:逆变
in
关键字用于声明一个泛型类型是逆变的。逆变允许你将该泛型类型用于消费(即输入参数),但不能用于返回值。逆变的类型参数可以安全地从父类型转换到子类型。例如,Consumer<in T>
表示该类型只能作为消费者,它可以接收 T
或 T
的父类型的对象。逆变的核心思想是“只消费,不生产”
- 星号投影
*
- 是星号投影,用于表示未知类型。它的作用类似于
Java
中的 <? extends Object>
,但在 Kotlin
中,它更类似于 out Any?
。它表示该位置可以是任何类型
class MyArrayList<T> {}
var myNumerArrayList = MyArrayList<Number>()
var myIntArrayList = MyArrayList<Int>()
class MyArrayList<out T> {}
myNumerArrayList = myIntArrayList
class MyArrayList<in T> {}
myIntArrayList = myNumerArrayList
interface Producer<out T>{
fun get() : T
fun set(t: T)
}
interface Consumer<in T>{
fun set(t: T)
fun get() : T
}
var list: List<*> ?= null
inline fun <reified T> check(value: Any?) {
if (value is T) {
println("和T类型匹配")
} else {
println("和T类型不匹配")
}
}
check<Int>(26)
check<Int>("Yang")
和T类型匹配
和T类型不匹配
inline fun <reified T : Any> getClass(): KClass<T> {
return T::class
}
inline fun <reified T : Any> getJavaClass(): Class<T> {
return T::class.java
}
println(getClass<String>())
println(getJavaClass<String>())
class java.lang.String
class java.lang.String