目录
1. kotlin 定义泛型类
// 定义泛型类
open class GenericDemo<T>(open var field: T? = null)
// 继承泛型类
class SubGeneric(param: Float) : GenericDemo<Float>() {
override var field: Float? = param
}
fun main() {
val demo1 = GenericDemo<String>("demo1")
val demo2 = GenericDemo<Int>(2)
val demo3 = GenericDemo(true)
val demo4 = SubGeneric(3.14f)
println("${demo1.field}, ${demo2.field}, ${demo3.field}, ${demo4.field}") // demo1, 2, true, 3.14
}
2. kotlin 定义类型变
kotlin 使用 out 定义型变。即向外提供的类型,不能向其写入,同 java 的通配符上限
// name 只能用 val 声明,否则会有 setter 方法向其写入
class Fruit<out T>(private val name: T) {
fun getFruitName(): T {
return name
}
}
fun main() {
val apple = Fruit("apple")
// Fruit<String> 可以被赋值给 Fruit<Any>
val fruit: Fruit<Any> = apple
println(fruit.getFruitName())
}
3. kotlin 定义类逆变
kotlin 使用 in 定义逆变。即向里写入的类型,不能向外提供,同 java 通配符下限
class Reverse<in T> {
fun setValue(value: T) {
println("value: $value")
}
}
fun main() {
var reverse1 = Reverse<Int>()
val reverse2 = Reverse<Number>()
reverse2.setValue(3.14f) // value: 3.14
// 可以将 Reverse<Number> 赋值给 Reverse<Int>
reverse1 = reverse2
}
4. kotlin 定义调用处型变
在调用原本不支持型变的类时,如 ArrayList,可以在使用时用 out 修饰泛型支持型变
fun main() {
var arrNumber: ArrayList<out Number> = arrayListOf(1, 0.2, 3f)
val arrayInt: ArrayList<Int> = arrayListOf(1, 2, 3)
// arrNumber 可以接受元素为 Int 类型集合
arrNumber = arrayInt
println(arrNumber) // [1, 2, 3]
}
5. kotlin 定义调用处逆变
在调用原本不支持型变的类时,如 ArrayList,可以在使用时用 in 修饰泛型支持逆变
fun main() {
var arrInt: ArrayList<in Int> = arrayListOf(1, 2, 3)
val arrNum: ArrayList<Number> = arrayListOf(1, 0.2, 3f)
// arrInt 可以接受元素为 Number 类型集合
arrInt = arrNum
println(arrInt) // [1, 0.2, 3.0]
}
6. kotlin 星号投影
fun main() {
// val list : ArrayList = arrayListOf(1, 2, 3) // 编译错误
// 使用 * 号,等价于 out Any? 可接受任意类型的元素
val list1: ArrayList<*> = arrayListOf(1, 0.2, "3")
val list2: ArrayList<out Any?> = arrayListOf(1, 0.2, "3")
println("list1: $list1, list2: $list2") // list1: [1, 0.2, 3], list2: [1, 0.2, 3]
}
7. kotlin 定义泛型函数
fun <T> printSelf(param: T) {
println(param)
}
8. kotlin 使用 reified 修饰泛型
使用 reified 修饰 泛型后,可以将泛型变成具体化的类型(泛型具型化),从而可以使用其相关方法
inline fun <reified T> printSelfName() {
val name = T::class.simpleName
println("class simple name: $name")
}
fun main() {
printSelfName<Int>() // class simple name: Int
printSelfName<String>() // class simple name: String
}
9. kotlin 定义泛型上限
// 定义类泛型上限
class Container<T : Number>(var param: T)
// 定义方法泛型上限
fun <T : Number> sum(vararg param: T) {
var sum = 0.0
param.forEach {
sum += it.toDouble()
}
println("求和: $sum")
}
fun main() {
val c1 = Container<Int>(1)
val c3 = Container<Long>(3L)
val c4 = Container<Float>(3.14f)
sum(1, 2f, 3.0) // 求和: 6.0
}
// 类泛型指定多个上限
class Test<T>() where T : Callable<T>, T : Runnable {}
// 方法泛型指定多个上限
fun <T> func(param: T) where T : Callable<T>, T : Runnable {}