Kotlin 泛型 #
一、泛型概述 #
泛型允许编写类型安全的代码,同时保持灵活性。
二、泛型类 #
2.1 基本语法 #
kotlin
class Box<T>(val value: T)
val intBox = Box(10)
val stringBox = Box("Hello")
2.2 泛型属性 #
kotlin
class Container<T> {
var value: T? = null
fun set(value: T) {
this.value = value
}
fun get(): T? = value
}
2.3 多类型参数 #
kotlin
class Pair<K, V>(val key: K, val value: V)
val pair = Pair("name", "Kotlin")
三、泛型函数 #
3.1 基本语法 #
kotlin
fun <T> singletonList(item: T): List<T> {
return listOf(item)
}
val list = singletonList(10)
3.2 多类型参数 #
kotlin
fun <K, V> mapOf(key: K, value: V): Map<K, V> {
return mapOf(key to value)
}
3.3 类型约束 #
kotlin
fun <T : Comparable<T>> max(a: T, b: T): T {
return if (a > b) a else b
}
max(10, 20)
max("a", "b")
3.4 多重约束 #
kotlin
fun <T> process(value: T) where T : CharSequence, T : Comparable<T> {
if (value > "test") {
println(value)
}
}
四、型变 #
4.1 不变 #
kotlin
class Box<T>(val value: T)
// Box<Int> 不是 Box<Number> 的子类型
val intBox: Box<Int> = Box(10)
// val numberBox: Box<Number> = intBox // 错误
4.2 协变 (out) #
kotlin
interface Producer<out T> {
fun produce(): T
}
class NumberProducer : Producer<Number> {
override fun produce(): Number = 10
}
val producer: Producer<Number> = NumberProducer()
val anyProducer: Producer<Any> = producer // 正确
4.3 逆变 (in) #
kotlin
interface Consumer<in T> {
fun consume(value: T)
}
class NumberConsumer : Consumer<Number> {
override fun consume(value: Number) {
println(value)
}
}
val consumer: Consumer<Number> = NumberConsumer()
val intConsumer: Consumer<Int> = consumer // 正确
4.4 型变总结 #
| 型变 | 关键字 | 方向 | 场景 |
|---|---|---|---|
| 协变 | out | 生产者 | 只读 |
| 逆变 | in | 消费者 | 只写 |
| 不变 | 无 | 无 | 读写 |
五、星投影 #
5.1 基本用法 #
kotlin
fun printList(list: List<*>) {
list.forEach { println(it) }
}
5.2 限制 #
kotlin
fun process(box: Box<*>) {
val value = box.value // Any?
// box.set(value) // 错误:不能写入
}
六、泛型擦除 #
6.1 运行时类型检查 #
kotlin
fun <T> isType(value: Any): Boolean {
// return value is T // 错误:不能检查泛型类型
return false
}
6.2 reified #
kotlin
inline fun <reified T> isType(value: Any): Boolean {
return value is T
}
isType<String>("Hello") // true
isType<Int>("Hello") // false
6.3 获取泛型类型 #
kotlin
inline fun <reified T> getTypeName(): String {
return T::class.simpleName ?: "Unknown"
}
getTypeName<String>() // "String"
getTypeName<Int>() // "Int"
七、实战示例 #
7.1 泛型 Repository #
kotlin
interface Repository<T, ID> {
fun findById(id: ID): T?
fun save(entity: T): T
fun delete(id: ID)
}
class UserRepository : Repository<User, Int> {
override fun findById(id: Int): User? { }
override fun save(entity: User): User { }
override fun delete(id: Int) { }
}
7.2 泛型 Result #
kotlin
sealed class Result<out T> {
data class Success<T>(val data: T) : Result<T>()
data class Error(val message: String) : Result<Nothing>()
}
fun <T> Result<T>.onSuccess(action: (T) -> Unit): Result<T> {
if (this is Result.Success) action(data)
return this
}
fun <T> Result<T>.onError(action: (String) -> Unit): Result<T> {
if (this is Result.Error) action(message)
return this
}
7.3 泛型扩展函数 #
kotlin
fun <T : Number> T.toDoubleValue(): Double {
return this.toDouble()
}
10.toDoubleValue()
10.5.toDoubleValue()
八、最佳实践 #
8.1 命名约定 #
kotlin
// 单类型参数
class Box<T>
// 多类型参数
class Map<K, V>
// 特定含义
class Repository<E, ID>
8.2 使用 out/in #
kotlin
// 只读:使用 out
interface Source<out T> {
fun next(): T
}
// 只写:使用 in
interface Sink<in T> {
fun put(value: T)
}
8.3 使用 reified 简化代码 #
kotlin
// 不使用 reified
fun <T> create(clazz: Class<T>): T = clazz.newInstance()
// 使用 reified
inline fun <reified T> create(): T = T::class.java.newInstance()
九、总结 #
泛型要点:
| 概念 | 说明 |
|---|---|
| 泛型类 | class Box<T> |
| 泛型函数 | fun <T> foo() |
| 类型约束 | <T : Comparable<T>> |
| 协变 | out T |
| 逆变 | in T |
| 具体化 | reified T |
下一步,让我们学习 注解!
最后更新:2026-03-27