前言
Kotlin 2.3.20 正式版已于 2026 年 3 月 正式发布! 🎉
距离上一个大版本 Kotlin 2.3 发布才过去三个月,JetBrains 团队又马不停蹄地为我们端上了这道"加餐"。虽然是一个增量版本,但这次更新的含金量可一点都不低。
如果你正在做 Spring Boot 后端、KMP 跨平台或者 Compose 项目,这个版本绝对值得你关注。废话不多说,让我们一起来看看这 6 大核心更新!
更新一:JPA 插件大升级:自动 all-open,Spring 开发者狂喜
JPA 插件现在自动处理 all-open,彻底告别手动配置的烦恼
🤔 以前的痛点
用 Kotlin 写 Spring Boot 项目的同学一定经历过这种"仪式":Kotlin 的类默认是 final 的,但 JPA/Hibernate 需要实体类是 open 的才能生成代理对象。于是你不得不:
- 要么给每个实体类手动加
open关键字 - 要么配置
all-open编译器插件,再手动指定注解列表
一不小心忘了配,运行时就会遇到神秘的 LazyInitializationException,排查半天才发现是忘了 open... 🤦
// build.gradle.kts - 以前需要手动配置
plugins {
kotlin("jvm")
kotlin("plugin.jpa")
kotlin("plugin.allopen") // 必须额外引入!
}
allOpen {
annotation("javax.persistence.Entity") // 手动指定
annotation("javax.persistence.Embeddable") // 手动指定
annotation("javax.persistence.MappedSuperclass") // 手动指定
}
✅ 现在的方案
Kotlin 2.3.20 中,kotlin.plugin.jpa 插件现在会自动应用 all-open 编译器插件!
它会自动识别以下注解,将标注的类标记为 open:
javax.persistence.Entityjavax.persistence.Embeddablejavax.persistence.MappedSuperclassjakarta.persistence.Entity(完整支持 Jakarta 命名空间)
// build.gradle.kts - 现在只需要一行!
plugins {
kotlin("jvm")
kotlin("plugin.jpa") // 自动包含 all-open,开箱即用 ✨
}
💡 Maven 用户福利:引入
kotlin-maven-noarg依赖后,现在也会隐式包含kotlin-maven-allopen,真正实现零配置。
更新二:基于名称的解构声明:告别位置依赖的噩梦
🤔 以前的痛点
Kotlin 的解构声明一直是基于位置的——变量按 component1()、component2() 的顺序匹配。这意味着一旦数据类的属性顺序发生变化,或者你记错了顺序,就会得到错误的赋值且没有任何编译警告:
data class User(val username: String, val email: String)
val user = User("alice", "alice@example.com")
val (email, username) = user
// ⚠️ 看起来没问题?实际上 email = "alice",username = "alice@example.com"
// 完全搞反了!但编译器不会报错!
这种 Bug 隐蔽性极强,生产环境出了问题排查起来能让人崩溃。
✅ 现在的方案
Kotlin 2.3.20 引入了基于名称的解构声明(实验性),变量将根据属性名称进行匹配,而不是位置:
data class User(val username: String, val email: String)
val user = User("alice", "alice@example.com")
// 基于名称的解构 - 使用 = 指定对应的属性名
val (mail = email, name = username) = user
println(name) // ✅ 正确输出: alice
println(mail) // ✅ 正确输出: alice@example.com
🔧 如何启用:需添加编译器选项
-Xname-based-destructuring=only-syntax,目前为实验性功能。
这个特性虽然还在实验阶段,但方向绝对是正确的。尤其是在大型项目中,数据类属性顺序的调整时有发生,有了名称匹配就多了一层安全保障。
更新三:🔧 构建工具全面优化:Gradle 9.3 + Maven 零配置
Gradle 兼容性扩展
- 支持范围:现在完全兼容 Gradle 7.6.3 ~ 9.3.0 的所有版本
- BTA 默认启用:Kotlin/JVM 编译现在默认使用 Build Tools API (BTA),这是编译基础设施的内部优化,为未来更快的编译器迭代铺路
Maven 项目配置极简化
这是 Maven 用户的大好消息。以前在 Maven 中配置 Kotlin 需要手动添加源码目录和标准库依赖,现在只需一行 <extensions>true</extensions> 即可自动完成:
Before(以前):
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<!-- 然后手动配置 source roots、添加 stdlib 依赖... -->
</plugin>
After(现在):
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>2.3.20</version>
<extensions>true</extensions> <!-- 一行搞定! -->
</plugin>
自动完成的事情:
- ✅ 自动注册
src/main/kotlin和src/test/kotlin为源根目录 - ✅ 自动添加
kotlin-stdlib依赖
💡 如果你有特殊需求不想要这些默认行为,可以通过设置
<kotlin.smart.defaults.enabled>false</kotlin.smart.defaults.enabled>关闭。
更新四:☕ Lombok 插件升级至 Alpha:Java 迁移更丝滑
🤔 以前的痛点
很多团队在从 Java 向 Kotlin 迁移的过程中,会面临一个尴尬的"过渡期"——Java 代码中大量使用了 Lombok 的 @Data、@Builder、@Getter/@Setter 等注解。Kotlin 代码如果要调用这些 Lombok 生成的方法,以前需要借助实验性的编译器插件,稳定性一直让人提心吊胆。
✅ 现在的进展
Kotlin 2.3.20 中,Lombok 编译器插件从实验阶段正式提升到 Alpha 阶段。
这意味着:
- JetBrains 已将其纳入正式产品化路线
- Kotlin 代码可以更稳定地直接使用 Java 中 Lombok 生成的声明
- 对于正在做 Java → Kotlin 渐进迁移的团队来说,这是一个非常积极的信号
// Kotlin 代码中直接调用 Java Lombok 生成的方法
val user = JavaUser.builder()
.name("Alice")
.email("alice@example.com")
.build()
println(user.name) // 直接调用 Lombok 生成的 getter ✅
五、🌐 跨平台能力进化:Wasm 性能飞跃 + Native 互操作升级
Kotlin/Wasm 性能飞跃 🚀
这次 Wasm 的更新可以说是最"硬核"的部分:
- 字符串操作性能提升最高 4.6 倍(通过 JS String builtins 优化)
- Wasm 二进制文件体积减小约 5%
- 编译内存消耗显著降低,清洁构建时间改善 65%
此外还引入了实验性的 @nativeInvoke 注解,允许将 Kotlin 对象像 JavaScript 函数一样调用:
@nativeInvoke
external class JsFunction {
operator fun invoke(arg: String): String
}
Kotlin/JS 新能力
- TypeScript 可以实现 Kotlin 接口了!通过
-Xenable-implementing-interfaces-from-typescript选项启用 - SWC 编译支持(实验性):引入对 SWC 的支持用于代码转译,进一步加速编译
Kotlin/Native 互操作升级
引入了新的 C/ObjC 互操作模式(实验性),解决 KMP 库在不同编译器版本间的兼容性问题:
// build.gradle.kts
kotlin {
targets.withType<KotlinNativeTarget> {
compilations.all {
compileTaskProvider.configure {
compilerOptions {
freeCompilerArgs.addAll("-Xccall-mode", "direct")
}
}
}
}
}
⚠️ 该功能仍处于实验阶段,建议暂时不要用于发布库。
六、📦 标准库 & 编译器其他改进
新增 Map.Entry.copy() API
解决了一个长期的小痛点:从 MutableMap 获取 entry 并存储引用后,原 Map 的修改可能导致 entry 失效。
@OptIn(ExperimentalStdlibApi::class)
fun main() {
val mutableMap = mutableMapOf("key" to "value")
// 以前:entry 引用可能在 map 修改后失效
val entry = mutableMap.entries.first()
// 现在:创建不可变副本,安全保存
val safeCopy = entry.copy() // ✨ 新 API
mutableMap["key"] = "newValue"
println(safeCopy.value) // 仍然输出: value ✅
}
Kotlin/JVM 空安全增强
- 支持 Vert.x
@Nullable注解:编译器现在能识别io.vertx.codegen.annotations.Nullable - 支持 Java 不可变集合注解:
@Unmodifiable和@UnmodifiableView标记的 Java 集合在 Kotlin 中将被视为只读
// Java 中声明
@Unmodifiable
List<String> getNames();
// Kotlin 中使用
val names: List<String> = javaObj.getNames() // ✅ 自动识别为只读
val mutableNames: MutableList<String> = javaObj.getNames() // ⚠️ 类型不匹配警告
📌 计划在 Kotlin 2.5.0 中,上述警告将升级为编译错误。
⚠️ 重要弃用提醒
在升级前,请注意以下破坏性变更:
- 弃用 Intel 芯片 Apple 目标:
macosX64、tvosX64、watchosX64已弃用,计划下一版本移除 - 上下文接收器已退场:实验性的 context receivers 正式被 context parameters 取代
- 上下文参数重载决议变更:仅因上下文参数不同的重载可能导致编译二义性错误
升级建议
Kotlin 持续进化,拥抱更广阔的开发场景
📊 该版本值得升级吗?
| 项目类型 | 推荐程度 | 理由 |
|---|---|---|
| Spring Boot / JPA 项目 | ⭐⭐⭐⭐⭐ | JPA 插件自动 all-open,体验飞升 |
| Java→Kotlin 迁移项目 | ⭐⭐⭐⭐ | Lombok Alpha 支持更稳定 |
| KMP 跨平台项目 | ⭐⭐⭐⭐ | Native 互操作 + Wasm 性能提升 |
| 纯 Android 项目 | ⭐⭐⭐ | 建议等正式版稳定后再升级 |
| Maven 新项目 | ⭐⭐⭐⭐⭐ | 零配置体验太香了 |
🔮 升级方式
在 build.gradle.kts 中修改 Kotlin 版本即可:
plugins {
kotlin("jvm") version "2.3.20"
// 或者在 settings.gradle.kts 中统一管理
}
最新的 IntelliJ IDEA 和 Android Studio 已内置支持,无需额外更新 IDE 插件。
展望
这次的更新,每一项改进都击中开发者的痛点:
- JPA 插件的 all-open 整合:彻底消灭 Kotlin + Spring 的经典痛点
- Lombok Alpha 升级:让长期烦恼于Java 迁移 Kotlin 的团队给了更好的解决方案
- Kotlin/Native 新互操作模式:持续加强跨平台的短板
- 构建工具链的持续打磨,不管你用 Gradle 还是 Maven
从 Kotlin 2.3 系列的更新节奏可以看出,JetBrains 正在多条战线同步推进:
- 语言层面:基于名称的解构、上下文参数等特性正在逐步成熟
- 跨平台层面:Wasm 性能持续优化,JS 互操作能力不断增强
- 工具链层面:Maven/Gradle 配置越来越简洁,开发体验持续打磨
- 生态层面:对 Spring、JPA、Lombok 的支持越来越好,拥抱 Java 生态更加彻底
Kotlin 正在从"一门好用的 Android 语言"蜕变为"一门全场景的现代编程语言"。未来可期!
参考资料: