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