Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 类型擦除与实化类型参数(reified)

类型擦除与实化类型参数(reified)

1. 类型擦除的概念

在 Java 和 Kotlin 的泛型中,类型擦除(Type Erasure) 是指泛型类型信息在编译后会被擦除,运行时无法直接获取泛型的实际类型参数。例如:

fun <T> checkType(item: T) {
    // 编译错误:无法直接获取 T 的实际类型
    // println(T::class.java)
}

2. 类型擦除的限制

由于类型擦除,以下操作无法直接实现:

  • 运行时检查泛型类型(如 item is T)
  • 获取泛型类的具体类型参数(如 T::class)
  • 基于类型参数创建实例(如 T())

3. 实化类型参数(reified)

Kotlin 通过 reified 关键字解决部分类型擦除问题,但仅适用于内联函数(inline)。实化类型参数允许在函数体内访问类型信息:

inline fun <reified T> checkType(item: Any) {
    if (item is T) {  // 可检查类型
        println("Item is of type ${T::class.simpleName}")
    }
}

// 使用示例
checkType<String>("Kotlin")  // 输出: "Item is of type String"

关键特性:

  • 必须与 inline 函数结合使用(编译器会将具体类型替换到调用处)
  • 支持 T::class 获取 KClass 对象
  • 允许类型检查(is T)和类型转换(as T)

4. 实际应用场景

案例1:简化 Gson 解析

inline fun <reified T> fromJson(json: String): T {
    return Gson().fromJson(json, T::class.java)
}

// 直接获取具体类型
val user = fromJson<User>("""{"name": "Alice"}""")

案例2:依赖注入

inline fun <reified T> inject(): T {
    return ServiceLocator.resolve(T::class)
}

val service = inject<AuthService>()

5. 注意事项

  • 局限性:reified 只能用于内联函数,无法用于类或属性
  • 性能:内联会导致代码膨胀,但通常影响可忽略
  • Java 互操作:Java 代码无法调用带 reified 参数的 Kotlin 函数

6. 替代方案

当无法使用 reified 时,可通过传递 KClass 参数实现类似功能:

fun <T : Any> parseJson(json: String, type: KClass<T>): T {
    return Gson().fromJson(json, type.java)
}

提示:优先使用 reified 简化代码,但在需要动态类型或非内联场景时选择传统方式。

Last Updated:: 5/21/25, 7:58 PM