一句话总结:
APT 是 Java 时代的“代码秘书”,而在 Kotlin-First 的今天,KSP 才是那位更懂 Kotlin、速度更快的“智能助理”。选择 KSP,意味着选择更快的编译速度和更强的语言特性支持。
第一篇章:“古典时代”——APT 的权柄与枷锁
APT (Annotation Processing Tool) 是 Java 平台的基石之一,它赋予了我们在编译期动态生成代码的能力,从而催生了 ButterKnife, Dagger2, ARouter 等一代神器。
APT 的核心工作流(经典三部曲)
你的文章已经出色地总结了这一流程:
- 定义注解: 创建带有
@Retention(RetentionPolicy.CLASS)的注解。 - 实现处理器: 继承
AbstractProcessor,在process方法中扫描注解,并使用JavaPoet等库生成.java文件。 - 注册处理器: 通过
META-INF/services路径下的文件进行注册。
Kotlin 时代的“枷锁”——kapt
APT 的设计完全面向 Java。当我们在 Kotlin 项目中使用它时,必须借助一个名为 kapt (Kotlin Annotation Processing Tool) 的 Gradle 插件。kapt 的工作流暴露了 APT 的局限性:
Kotlin 源码 -> kapt 生成 Java 存根 -> APT 处理 Java 存根 -> 生成 .java 代码
这个**“生成存根”**的额外步骤,是导致编译速度缓慢的罪魁祸首。
第二篇章:“现代革命”——KSP (Kotlin Symbol Processing) 的崛起
为了彻底解决 kapt 的性能瓶颈,并提供一个真正面向 Kotlin 的 API,Google 推出了 KSP。
什么是 KSP?
KSP 是一个独立于 Kotlin 编译器的、可直接解析 Kotlin 源码的注解处理工具。
KSP 的革命性优势:
-
性能飞跃(快达 2 倍):
KSP 的工作流更直接:
Kotlin 源码 -> KSP 直接处理 -> 生成 .kotlin 或 .java 代码
它砍掉了“生成 Java 存根”这一最耗时的步骤,直接带来了巨大的编译速度提升。
-
Kotlin 语言的原生理解:
KSP 能完全理解并访问 Kotlin 的语言特性,例如:
-
suspend函数 -
默认参数
-
可空性 (
?) -
......
而 APT 只能看到这些特性被转换成 Java 后的“阉割版”,丢失了大量有用信息。
-
-
更简洁的 API:
KSP 提供了更现代化、更符合 Kotlin 风格的 API (SymbolProcessorProvider, SymbolProcessor, Resolver),相比 APT 繁琐的 javax.lang.model API,学习和使用成本更低。
KSP 实践一瞥:
// KSP 的处理器接口
class MyProcessorProvider : SymbolProcessorProvider {
override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
return MyProcessor(environment.codeGenerator)
}
}
class MyProcessor(private val codeGenerator: CodeGenerator) : SymbolProcessor {
override fun process(resolver: Resolver): List<KSAnnotated> {
// API 更直观
val symbols = resolver.getSymbolsWithAnnotation("com.example.MyAnnotation")
// ... 处理 symbols 并通过 codeGenerator 生成代码 ...
return emptyList() // 返回无法处理的 symbols
}
}
第三章:2025 年的技术选型指南
| 对比维度 | APT (通过 kapt 用于 Kotlin) | KSP |
|---|---|---|
| 核心原理 | 先将 Kotlin 生成 Java 存根,再用 Java 的工具处理 | 直接解析 Kotlin 源码 |
| 编译性能 | 慢,存在 kapt 带来的额外开销 | 快(通常是 kapt 的 1.5 到 2 倍) |
| Kotlin 支持 | 有限,只能看到 Java 视角的 Kotlin | 原生、完整地支持所有 Kotlin 语言特性 |
| 生态系统 | 正在逐步被 KSP 取代 | 主流库(Room, Dagger, Moshi, Hilt...)的首选 |
| 增量编译 | 支持较弱,易被破坏 | 设计上对增量编译更友好 |
你的决策清单:
-
如果你正在为一个 Kotlin-First 的项目开发一个新的注解处理器:
- 答案是唯一的:使用 KSP。 没有任何理由再选择
kapt。
- 答案是唯一的:使用 KSP。 没有任何理由再选择
-
如果你正在使用一个只提供 APT 支持的第三方库:
- 你被迫需要使用
kapt插件来兼容它。此时,你需要意识到它可能成为你项目编译速度的瓶颈。可以向该库的作者提议,希望他们支持 KSP。
- 你被迫需要使用
-
如果你正在维护一个纯 Java 的 Android 项目或库:
- APT 仍然是标准的、正确的选择。 KSP 主要的优势体现在 Kotlin 生态中。
结论:
APT 是一项伟大而经典的技术,为 Java 生态的自动化代码生成立下了汗馬功勞。但在 Android 的新时代,KSP 已经从一个“备选项”成长为“默认的最优解”。理解 APT 是为了 appreciation 历史,而拥抱 KSP 则是为了 investment 未来。