// 没有泛型:只能用 Any,需要手动强转
val list = listOf(1, "hello", true)
val first = list[0] as Int // 每次都要强转,麻烦且不安全
// 有泛型:类型自动推断,安全
val list = listOf(1, 2, 3)
val first: Int = list[0] // 自动知道是 Int,不需要强转
1.2 泛型的本质
复制代码
┌─────────────────────────────────────┐
│ Generic Type │
│ │
│ List<T> ←──── T 是类型参数 │
│ Map<K,V> ←──── K,V 是类型参数 │
│ Pair<A,B> ←─── A,B 是类型参数 │
└─────────────────────────────────────┘
调用时:
List<String> → T = String
List<Int> → T = Int
Map<String,Int> → K=String, V=Int
二、泛型类与函数
2.1 泛型类
kotlin复制代码
// 泛型类
class Box<T>(val value: T) {
fun get(): T = value
}
// 使用
val intBox = Box(123) // 自动推断 T = Int
val stringBox = Box("hello") // 自动推断 T = String
val explicitlyTyped = Box<Int>(456)
// 多类型参数
class PairBox<A, B>(val first: A, val second: B)
// 使用多类型参数
val pair = PairBox("name", 25) // PairBox<String, Int>
2.2 泛型函数
kotlin复制代码
// 泛型函数
fun <T> singletonList(item: T): List<T> = listOf(item)
// 多个类型参数
fun <K, V> makePair(key: K, value: V): Pair<K, V> = Pair(key, value)
// 使用
val list = singletonList(42) // List<Int>
val pair = makePair("age", 30) // Pair<String, Int>
2.3 类型约束
kotlin复制代码
// T 必须继承或实现 Comparable
fun <T : Comparable<T>> max(a: T, b: T): T {
return if (a >= b) a else b
}
// 使用
max(1, 2) // OK,Int 实现了 Comparable
max("a", "b") // OK,String 实现了 Comparable
// max(1, "a") // ERROR,类型不一致
// 多个约束
fun <T> sortAndPrint(list: List<T>) where T : Comparable<T>, T : Any {
list.sorted().forEach { println(it) }
}
// 生产者用 out,只能读取,不能写入
class Producer<out T>(val item: T) {
fun produce(): T = item
// fun consume(item: T) // ERROR,不能接收 T
}
// 效果:Producer<String> 是 Producer<Any> 的子类
val stringProducer: Producer<String> = Producer("hello")
val anyProducer: Producer<Any> = stringProducer // OK!
val item: Any = anyProducer.produce() // 读取的一定是 Any 或子类
// JDK 的 Comparable 就是协变
// public interface Comparable<out T>
// Kotlin 的 List 也是协变(只读)
// public interface List<out E>
// Function 的逆变
// public interface Function1<in P1, out R>
// P1 是逆变参数(输入),R 是协变参数(输出)
四、泛型约束与类型擦除
4.1 类型擦除
kotlin复制代码
// JVM 的泛型是通过类型擦除实现的
class MyBox<T> {
fun get(): T? = null
}
// 编译后变成
class MyBox {
fun get(): Object? = null // T 被擦除为 Object
}
// 所以运行时无法直接判断泛型类型
val list: List<String> = listOf("a")
// list is List<Int> // ERROR,运行时不知道 T 是什么
4.2 实化类型(Reified)
kotlin复制代码
// 普通泛型函数不能检查类型
fun <T> checkType(item: Any) = item is T // ERROR
// 内联函数可以使用 reified
inline fun <reified T> checkType(item: Any) = item is T
// 现在可以了
checkType<String>("hello") // true
checkType<String>(123) // false
4.3 星号投影(*)
kotlin复制代码
// 不关心具体类型,用 *
val list: List<*> = listOf("a", "b", "c")
val any: Any = list[0] // 安全的未知类型
// 用于不知道类型参数的情况
fun printFirst(list: List<*>) {
println(list.firstOrNull())
}
/**
* 自定义 Lazy 延迟加载委托
*
* @param initializer 初始化函数,返回 T 类型的值
*/
fun <T> myLazy(initializer: () -> T): Lazy<T> = MyLazyImpl(initializer)
/**
* Lazy 接口的自定义实现
*/
class MyLazyImpl<T>(private val initializer: () -> T) : Lazy<T> {
private var _cachedValue: Any? = UNINITIALIZED
private var _isInitialized = false
override val value: T
get() {
if (_isInitialized) {
@Suppress("UNCHECKED_CAST")
return _cachedValue as T
}
val result = initializer()
_cachedValue = result
_isInitialized = true
return result
}
override fun isInitialized(): Boolean = _isInitialized
companion object {
private object UNINITIALIZED
}
}
// 使用方式完全相同
val value: String by myLazy {
println("只执行一次!")
"延迟加载的结果"
}
5.3 线程安全版本
kotlin复制代码
import java.util.concurrent.atomic.AtomicReference
import java.util.concurrent.locks.ReentrantLock
/**
* 线程安全的 Lazy 委托实现
*/
class ThreadSafeLazy<T>(private val initializer: () -> T) : Lazy<T> {
@Volatile
private var _value: Any? = UNINITIALIZED
@Volatile
private var _lock = ReentrantLock()
override val value: T
get() {
if (_value !== UNINITIALIZED) {
@Suppress("UNCHECKED_CAST")
return _value as T
}
_lock.lock()
try {
if (_value !== UNINITIALIZED) {
@Suppress("UNCHECKED_CAST")
return _value as T
}
val result = initializer()
_value = result
return result
} finally {
_lock.unlock()
}
}
override fun isInitialized(): Boolean = _value !== UNINITIALIZED
companion object {
private object UNINITIALIZED
}
}
/**
* 创建线程安全的延迟加载属性
*/
fun <T> threadSafeLazy(initializer: () -> T): Lazy<T> = ThreadSafeLazy(initializer)
5.4 使用 CAS 无锁版本(更高效)
kotlin复制代码
import java.util.concurrent.atomic.AtomicReference
/**
* 使用 CAS 实现的无锁 Lazy(高性能版本)
*/
class LockFreeLazy<T>(private val initializer: () -> T) : Lazy<T> {
private val storage = AtomicReference<Any?>(UNINITIALIZED)
override val value: T
get() {
// 快速路径:已初始化
val stored = storage.get()
if (stored !== UNINITIALIZED) {
@Suppress("UNCHECKED_CAST")
return stored as T
}
// 慢速路径:需要初始化
return initialize()
}
private fun initialize(): T {
// 尝试用 initializer 初始化
val result = initializer()
// CAS:如果当前是 UNINITIALIZED,则设置为结果
if (storage.compareAndSet(UNINITIALIZED, result)) {
@Suppress("UNCHECKED_CAST")
return result as T
}
// 如果 CAS 失败,说明已经被其他线程初始化了
@Suppress("UNCHECKED_CAST")
return storage.get() as T
}
override fun isInitialized(): Boolean = storage.get() !== UNINITIALIZED
companion object {
private object UNINITIALIZED
}
}
5.5 最终的使用示例
kotlin复制代码
data class User(val name: String, val age: Int)
// 1. 基础版本(单线程)
val user1: User by myLazy {
println("初始化 User 1")
User("张三", 25)
}
// 2. 线程安全版本(多线程推荐)
val user2: User by threadSafeLazy {
println("初始化 User 2")
User("李四", 30)
}
// 3. 无锁版本(高性能)
val user3: User by LockFreeLazy {
println("初始化 User 3")
User("王五", 35)
}
// 测试
fun main() {
println("--- 开始 ---")
println(user1.name) // 第一次访问才会初始化
println(user1.name) // 第二次直接返回缓存值
println("--- 结束 ---")
}
六、委托(Delegation)机制
6.1 类委托
kotlin复制代码
// 接口
interface Base {
fun print()
}
// 实现类
class BaseImpl(val x: Int) : Base {
override fun print() = println(x)
}
// 委托类
class Derived(b: Base) : Base by b
// 使用
val b = BaseImpl(10)
val d = Derived(b)
d.print() // 调用委托对象的 print(),输出 10
6.2 属性委托
kotlin复制代码
// 定义可委托的属性接口
interface ReadOnlyProperty<in R, out T> {
operator fun getValue(thisRef: R, property: KProperty<*>): T
}
interface ReadWriteProperty<in R, T> {
operator fun getValue(thisRef: R, property: KProperty<*>): T
operator fun setValue(thisRef: R, property: KProperty<*>, value: T)
}
// 自定义委托
class MyDelegate(var value: String = "default") {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
println("读取: ${property.name}")
return value
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: String) {
println("写入: ${property.name} = $newValue")
value = newValue
}
}
// 使用
class Example {
var myProp: String by MyDelegate()
}
val e = Example()
e.myProp = "hello" // 输出: 写入: myProp = hello
println(e.myProp) // 输出: 读取: myProp, hello
6.3 常用标准库委托
kotlin复制代码
// 1. lazy - 延迟初始化
val heavyObject: ExpensiveClass by lazy { ExpensiveClass() }
// 2. observable - 属性变化监听
class User {
var name: String by Delegates.observable("default") { property, old, new ->
println("${property.name}: $old → $new")
}
}
// 3. vetoable - 可否决的变化
var score: Int by Delegates.vetoable(0) { property, old, new ->
new > old // 只允许增加
}
// 4. notNull - 可空但不初始化的属性
var lazyInitString: String by Delegates.notNull<String>()
七、泛型与委托的综合应用
7.1 委托工厂
kotlin复制代码
// 通用委托工厂
class DelegateFactory<T>(private val creator: () -> T) : Lazy<T> {
private var instance: T? = null
override val value: T
get() {
if (instance == null) {
instance = creator()
}
return instance!!
}
override fun isInitialized(): Boolean = instance != null
}
fun <T> delegate(creator: () -> T): Lazy<T> = DelegateFactory(creator)
// 使用
class DatabaseConnection {
companion object {
val instance: DatabaseConnection by delegate {
println("建立数据库连接...")
DatabaseConnection()
}
}
}
7.2 泛型委托的实战:属性校验
kotlin复制代码
class ValidatedProperty<T>(
initialValue: T,
private val validator: (T) -> Boolean
) {
private var _value: T = initialValue
operator fun getValue(thisRef: Any?, property: KProperty<*>): T = _value
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
require(validator(value)) { "Validation failed for ${property.name}: $value" }
_value = value
}
}
class User {
var name: String by ValidatedProperty("") { it.isNotBlank() }
var age: Int by ValidatedProperty(0) { it in 0..150 }
var email: String by ValidatedProperty("") { it.contains("@") }
}
// 使用
val user = User()
user.name = "张三"
// user.name = "" // ERROR: Validation failed for name:
// user.age = -1 // ERROR: Validation failed for age:
// user.email = "test" // ERROR: Validation failed for email:
7.3 泛型 + 委托 + 协变:事件总线
kotlin复制代码
/**
* 类型安全的事件总线
* 使用协变 out T 让订阅者可以接收子类事件
*/
class EventBus {
private val handlers = mutableMapOf<String, MutableList<(Any) -> Unit>>()
// 注册处理器,协变允许传入子类
@Suppress("UNCHECKED_CAST")
fun <T : Any> subscribe(eventType: KClass<T>, handler: (T) -> Unit) {
val key = eventType.qualifiedName ?: return
handlers.getOrPut(key) { mutableListOf() }.add(handler as (Any) -> Unit)
}
// 发布事件
@Suppress("UNCHECKED_CAST")
fun <T : Any> publish(event: T) {
val key = event::class.qualifiedName ?: return
handlers[key]?.forEach { it(event as Any) }
}
}
// 使用
sealed class Event
class ClickEvent(val x: Int, val y: Int) : Event()
class KeyEvent(val key: String) : Event()
val bus = EventBus()
bus.subscribe(ClickEvent::class) { event ->
println("点击坐标: ${event.x}, ${event.y}")
}
bus.subscribe(KeyEvent::class) { event ->
println("按键: ${event.key}")
}
bus.publish(ClickEvent(100, 200))
bus.publish(KeyEvent("Enter"))
package com.example.utils
import java.util.concurrent.atomic.AtomicReference
import java.util.concurrent.locks.ReentrantLock
/**
* 自定义 Lazy 延迟加载委托 - 单线程版本
*/
fun <T> myLazy(initializer: () -> T): Lazy<T> = MyLazyImpl(initializer)
class MyLazyImpl<T>(private val initializer: () -> T) : Lazy<T> {
private var _cachedValue: Any? = UNINITIALIZED
private var _isInitialized = false
override val value: T
get() {
if (_isInitialized) {
@Suppress("UNCHECKED_CAST")
return _cachedValue as T
}
val result = initializer()
_cachedValue = result
_isInitialized = true
return result
}
override fun isInitialized(): Boolean = _isInitialized
companion object {
private object UNINITIALIZED
}
}
/**
* 线程安全版本 - 使用 ReentrantLock
*/
class ThreadSafeLazy<T>(private val initializer: () -> T) : Lazy<T> {
@Volatile
private var _value: Any? = UNINITIALIZED
private val _lock = ReentrantLock()
override val value: T
get() {
if (_value !== UNINITIALIZED) {
@Suppress("UNCHECKED_CAST")
return _value as T
}
_lock.lock()
try {
if (_value !== UNINITIALIZED) {
@Suppress("UNCHECKED_CAST")
return _value as T
}
val result = initializer()
_value = result
return result
} finally {
_lock.unlock()
}
}
override fun isInitialized(): Boolean = _value !== UNINITIALIZED
companion object {
private object UNINITIALIZED
}
}
/**
* 高性能无锁版本 - 使用 CAS
*/
class LockFreeLazy<T>(private val initializer: () -> T) : Lazy<T> {
private val storage = AtomicReference<Any?>(UNINITIALIZED)
override val value: T
get() {
val stored = storage.get()
if (stored !== UNINITIALIZED) {
@Suppress("UNCHECKED_CAST")
return stored as T
}
val result = initializer()
if (storage.compareAndSet(UNINITIALIZED, result)) {
@Suppress("UNCHECKED_CAST")
return result as T
}
@Suppress("UNCHECKED_CAST")
return storage.get() as T
}
override fun isInitialized(): Boolean = storage.get() !== UNINITIALIZED
companion object {
private object UNINITIALIZED
}
}
// 使用方式
class Example {
// 单线程环境用这个
val heavyData: List<String> by myLazy {
println("加载数据...")
listOf("a", "b", "c")
}
// 多线程环境推荐这个
val threadSafeData: Map<String, Int> by ThreadSafeLazy {
println("加载配置...")
mapOf("timeout" to 5000)
}
// 高并发场景用这个
val cacheData: String by LockFreeLazy {
println("加载缓存...")
"cached_value"
}
}