Kotlin 的泛型系统支持定义上界和下界约束,包括协变和逆变。这些特性使得 Kotlin 的泛型类型系统更加灵活和强大。下面是对 Kotlin 泛型上界和下界的详细说明:
泛型的上界 (Upper Bounds)
上界用于限制泛型类型参数的类型范围。默认情况下,泛型类型参数具有一个隐式的上界 Any?
。你可以通过显式声明上界来进一步限制类型参数的类型范围。
示例
默认隐式上界:
1
class Box<T>(val value: T) // T 的隐式上界是 Any?
显式上界:
1
class Box<T : Number>(val value: T) // T 的上界是 Number,因此只能接受 Number 的子类型
多重上界: 如果需要使用多个上界,可以使用
where
子句来进行声明。1
2
3
4
5
6fun <T> ensureAllNonNull(vararg args: T) where T : Any, T : Comparable<T> {
for (arg in args) {
checkNotNull(arg)
println(arg)
}
}
泛型的下界 (Lower Bounds)
Kotlin 不直接提供显式声明下界的语法,但下界的概念可以通过协变和逆变来实现。协变和逆变是用于描述类型参数之间的子类型关系的概念,它们定义了类型参数在子类型化关系中的行为。
协变 (Covariance)
协变允许使用子类型来替代泛型类或接口的类型参数。在 Kotlin 中,协变使用关键字 out
来定义,表示泛型类型参数只能出现在输出位置(返回类型),不能出现在输入位置(函数参数)。
1 | interface Source<out T> { |
逆变 (Contravariance)
逆变允许使用超类型来替代泛型类或接口的类型参数。在 Kotlin 中,逆变使用关键字 in
来定义,表示泛型类型参数只能出现在输入位置(函数参数),不能出现在输出位置(返回类型)。
1 | interface Consumer<in T> { |
使用示例
以下是一个综合示例如 Box
类和函数如何利用泛型的上界和协变逆变:
1 | // 定义一个具有上界的泛型类 |
总结
- 上界:限制泛型类型参数的类型范围,默认是
Any?
,可以显式地使用:<类型>
来指定。 - 下界:Kotlin 没有直接的下界语法,但可以通过协变(
out
)和逆变(in
)来实现特定的行为。 - 协变:使用
out
关键字表示,只能用于返回类型,允许将子类型泛型对象赋值给超类型的变量。 - 逆变:使用
in
关键字表示,只能用于输入类型,允许将超类型泛型对象赋值给子类型的变量。