HoRain云--Kotlin泛型实战:从基础到高阶的完整指南

张开发
2026/4/21 17:08:28 15 分钟阅读

分享文章

HoRain云--Kotlin泛型实战:从基础到高阶的完整指南
HoRain 云小助手个人主页⛺️生活的理想就是为了理想的生活!⛳️ 推荐前些天发现了一个超棒的服务器购买网站性价比超高大内存超划算忍不住分享一下给大家。点击跳转到网站。目录⛳️ 推荐1. 基础写法2. 型变Variancein/ outout— 只读生产者协变in— 只写消费者逆变记忆口诀3. 声明处型变 vs 使用处型变4. 实化类型参数Reified5. 星投影Star Projection6. 上下界Upper/Lower Bounds7. 常见坑点与注意Kotlin 的泛型和 Java 一脉相承但更简洁安全还加了一些独有增强比如reified。下面用最实用的方式把核心点串起来。1. 基础写法class BoxT(var value: T) { fun getValue(): T value } val intBox Box(123) val strBox Box(hello)T就是类型参数使用时通常可自动推断。函数也能单独带泛型fun T wrap(value: T): ListT listOf(value) val list wrap(a) // ListString2. 型变Variancein/out这是 Kotlin 比 Java 通配符更容易理解的地方用来控制“谁可以赋值给谁”。out— 只读生产者协变表示“产出T但不消费T”。可以用父类容器指向子类实例class Producerout T(val data: T) val producerStr: ProducerString Producer(text) val producerAny: ProducerAny producerStr // ✅ 允许典型例子Listout E—— 只能取元素不能添加元素除了add(element: Nothing)这种无意义操作。in— 只写消费者逆变表示“消费T不产出T”。可以用子类容器指向父类实例class Consumerin T { fun accept(item: T) { println(item) } } val consumerAny: ConsumerAny Consumer() val consumerStr: ConsumerString consumerAny // ✅ 允许 consumerStr.accept(ok)典型例子Comparablein T—— 只需要“被比较”的能力不返回T。记忆口诀生产用 out往外拿消费用 in往里塞默认不变没有in/out时BoxA和BoxB互不兼容。3. 声明处型变 vs 使用处型变声明处型变直接在类上写out/in上面例子。使用处型变临时指定一次类似 Java? extends/super// 假设 Foo 是不变的 class FooT(val t: T) fun takeFoo(foo: Fooout Number) {} // 相当于 Foo? extends Number takeFoo(FooInt(10)) // ✅4. 实化类型参数ReifiedKotlin 独有的功能让泛型在运行时保留类型信息配合内联函数使用。inline fun reified T parseJson(json: String): T? Gson().fromJson(json, T::class.java) // 不用写成 parseJsonUser(json)直接 val user parseJsonUser(jsonString)必须是inline reified。常用在 JSON 反序列化、依赖查找、类型检查等场景。5. 星投影Star Projection当你不知道或不关心具体类型时用*fun printSize(list: List*) println(list.size) // size 不依赖元素类型 val strings: ListString listOf(a, b) printSize(strings) // ✅List*≈Listout Any?只能读成Any?。MutableList*读写都受限几乎只能读因为不知道写入什么类型才安全。6. 上下界Upper/Lower Bounds// T 必须是 Number 或其子类 fun T : Number double(num: T): Double num.toDouble() * 2 // 多个约束用 where fun T cloneIfCloseable(obj: T): T where T : Cloneable, T : Closeable { ... }默认上界是Any?不加?则非空。where用于多条件约束。7. 常见坑点与注意JVM 擦除普通泛型运行时类型丢失is T会报错 —— 优先用reified或传ClassT。不要乱用*MutableList*很难安全写入除非转成具体类型。逆变别返回 Tinterface Badin T { fun get(): T }编译会报错逻辑也不合理。内联函数里的reified不能递归调用自身否则编译器会拒绝。如果你需要看某个具体方向例如如何设计带泛型的 DSL、泛型与反射结合、或 Android 项目里常见的泛型场景我可以再给你展开写一段实用代码。你想先深入哪一块❤️❤️❤️本人水平有限如有纰漏欢迎各位大佬评论批评指正如果觉得这篇文对你有帮助的话也请给个点赞、收藏下吧非常感谢! Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧

更多文章