Kotlin Academy · 课时

实用的 Reified 模式:解析、DI 与序列化

将 reified 泛型应用于 JSON 解析、依赖解析和反射辅助函数。

第 4 / 4 课14 个步骤

实用的 Reified 模式:解析、DI 与序列化 是 CoddyKit 上的免费 Kotlin Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Kotlin Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Kotlin Academy 课程共包含 4 节课。

三种主要使用场景

具体化类型参数在 Kotlin 中的三种常见模式中尤为有用:JSON/数据解析、依赖注入和序列化辅助函数。每种模式都可以省去繁琐的 ::class.java 参数。

模式 1——类型安全的 JSON 解析

将 Gson 或 Jackson 封装在具体化扩展函数中,这样调用方就不必显式传入 Class:

inline fun <reified T> String.parseJson(): T =
    Gson().fromJson(this, T::class.java)

val user: User = jsonString.parseJson()

解析集合

解析泛型列表需要使用 TypeToken。借助 reified,您可以隐藏这部分复杂性:

inline fun <reified T> String.parseList(): List<T> {
    val type = object : TypeToken<List<T>>() {}.type
    return Gson().fromJson(this, type)
}

val users: List<User> = jsonString.parseList()

kotlinx.serialization 方式

kotlinx.serialization 内部已经使用了 reified。顶层的 decodeFromString() 依赖于 serializer(),后者是一个 reified inline 函数。

val user = Json.decodeFromString<User>(jsonString)
// equivalent to: Json.decodeFromString(serializer<User>(), jsonString)

模式 2——服务定位器 / DI

简单的服务定位器可以根据类型解析依赖,而不要求调用方传入 KClass:

object ServiceLocator {
    val registry = mutableMapOf<KClass<*>, Any>()
    inline fun <reified T : Any> get(): T =
        registry[T::class] as? T ?: error("No binding for ${T::class}")
    inline fun <reified T : Any> bind(instance: T) {
        registry[T::class] = instance
    }
}

在 Android 中获取 ViewModel

最常见的 Android 具体化模式:

inline fun <reified VM : ViewModel> ComponentActivity.viewModel(): VM =
    ViewModelProvider(this)[VM::class.java]

// Usage
val vm: MyViewModel by lazy { viewModel() }

模式 3——安全转换辅助函数

带回退机制的具体化转换辅助函数,比在各处显式使用 as? 更简洁:

inline fun <reified T> Any?.safeCast(): T? = this as? T

val name: String? = someAny.safeCast<String>()

检查集合中的类型

标准的 filterIsInstance() 是典型的具体化集合过滤器。您可以在它的基础上构建更高层的变体:

inline fun <reified T> List<Any>.onlyInstancesOf(block: (T) -> Unit) =
    filterIsInstance<T>().forEach(block)

items.onlyInstancesOf<Button> { it.setEnabled(true) }

按类型注册事件监听器

借助 reified,事件总线可以按类型分发事件,使用起来更加简洁:

class EventBus {
    val handlers = mutableMapOf<KClass<*>, (Any) -> Unit>()
    inline fun <reified E : Any> on(noinline handler: (E) -> Unit) {
        handlers[E::class] = { handler(it as E) }
    }
    fun post(event: Any) = handlers[event::class]?.invoke(event)
}

结合具体化与扩展函数

泛型接收者上的具体化扩展函数可以让 API 使用起来更流畅,同时保持类型安全:

inline fun <reified T : Any> SharedPreferences.get(key: String, default: T): T = when (T::class) {
    Int::class    -> getInt(key, default as Int) as T
    String::class -> getString(key, default as String) as T
    Boolean::class -> getBoolean(key, default as Boolean) as T
    else -> error("Unsupported type ${T::class}")
}

需要牢记的限制

请记住:reified 只能用于 inline 函数。类和接口不能拥有具体化类型参数。如果您需要在类中保存运行时类型信息,请改为存储一个 KClass 属性。

测试具体化辅助函数

具体化函数很容易测试:在单元测试中使用具体的类型参数调用它们,并断言输出的类型和值即可。不需要模拟类引用。

val result: List<String> = """["a","b","c"]""".parseList<String>()
assertEquals(listOf("a","b","c"), result)

快速检查

关于具体化函数,哪项说法是正确的?

回顾:实用的具体化模式

关键模式:

  • JSON 解析:隐藏 Class/TypeToken 参数
  • DI/服务定位器:无需 KClass 参数即可按类型解析
  • 安全转换和集合过滤
  • 按事件类型进行事件总线分发
  • SharedPreferences / 类型化键值存储
免费开始

用 AI 导师学习 Kotlin — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
51
课程
203

常见问题解答

「实用的 Reified 模式:解析、DI 与序列化」课时是免费的吗?

是的 — 「实用的 Reified 模式:解析、DI 与序列化」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Kotlin Academy 课程的其余内容,请升级到 CoddyKit PRO。 Kotlin Academy 课程共包含 4 节课。

「实用的 Reified 模式:解析、DI 与序列化」这节课中我会学到什么?

将 reified 泛型应用于 JSON 解析、依赖解析和反射辅助函数。 你通过在浏览器中直接运行的动手代码来练习 Kotlin Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Kotlin Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Kotlin Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「实用的 Reified 模式:解析、DI 与序列化」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Kotlin Academy 课中编写并运行代码吗?

能。每节 Kotlin Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. inline 函数:消除 Lambda 开销
  2. noinline 与 crossinline 修饰符
  3. reified 类型参数:在运行时访问 T
  4. 实用的 Reified 模式:解析、DI 与序列化
← 返回 Kotlin Academy