首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

IntelliJ IDEA 2025.1 发布 ,默认 K2 模式 | Android Studio 也将跟进

  • 25-04-18 17:40
  • 2582
  • 7447
juejin.cn

2025.1 版本已经发布,在此之前我们就聊过该版本的 《Terminal 又发布全新重构版本》,而现在 2025.1 中的 K2 模式也成为了默认选项。

可以预见,这个版本可能会包含不少大坑,为下个 Android Studio 祈祷。

首先有一点可以确定,随着 K2 模式成为默认选项,虽然 K1模式仍可使用,但后续 K1 将不再支持新语言特性和 IDE 优化,所以在 2025.1 里,你依然可以在 Language & FRameworks > Kotlin 里关闭 K2 模式,但是只能说「逃得了一时是一时」:

“K2” 对应的是 Kotlin 插件包含用于代码分析的 K2 Kotlin 编译器的内部版本,而 K1 模式使用 K1 编译器,IntelliJ IDEA 中内置的 Kotlin 编译器版本完全独立于项目构建文件中指定的版本,但它可能会影响项目中支持的 Kotlin 版本范围。

在之前的《K2 模式已发布稳定版》我们提到过,IntelliJ IDEA 的 K2 模式并不依赖于项目构建设置中指定的 Kotlin 编译器版本,K2 模式代表 IDE 中对 Kotlin 编辑场景支持的几乎完全重写,而使用 K2 编译器可以带来:

  • 高达 94% 的编译速度提升
  • 在初始化阶段的速度提高了 488%
  • 与之前的编译器相比,Kotlin K2 编译器在分析阶段的速度提高了 376%
  • ····

所以基于 K2 编译器能力的 K2 模式,在 Kotlin 代码分析、补全和导航速度方面取得了巨大进步,这体现在全新 IDE 下就是:

  • 提高代码分析的性能(如高亮、补全速度)
  • 更快的查找和跳转
  • 支持 Kotlin 2.0 及以上版本的新语言特性

而 IDE 一直以来都深度依赖 K1 ,所以其实在迁移到 K2 的过程中,会有大量的重写和功能重构,这也是 K2 到现在还一直需要打磨的原因。

而在 K1 到 K2 的变化里,其中最大的就是全新的 Kotlin Analysis API ,它提供了一种清晰稳定的方式来访问代码信息,并且不需要依赖编译器内部结构。

Kotlin Analysis API 在 K2 模式里采用模块化架构,支持 IDE 功能(如补全、检查)独立调用编译器的特定分析阶段(如解析或类型检查),避免不必要的全量分析,从而提升性能。

K2 编译器放弃了 K1 中隐式的 laziness,转而采用显式的分阶段代码分析架构, K2 编译器会分阶段分析代码(如 SUPER_TYPES 计算类的 supertypes ,TYPES 处理函数 signature types),每个阶段逐步为抽象语法树(AST)添加语义信息。

另外,在 K1 模式里 Kotlin Analysis API 的分析操作通常受限于单一的全局解析锁(global resolution lock),例如 Find Usages 等功能会持有全局锁,导致其他功能(如代码高亮、补全)无法并行执行,造成性能瓶颈。

而 K2 编译器的解析逻辑是并发容忍(concurrency-tolerant),Kotlin Analysis API 利用这一特性,消除了全局锁,API 现在支持同时分析多个声明(declarations),即使在复杂场景(如两个函数相互调用)中也能高效处理:

image-20250417140125624

虽然 K2 编译器目前还是使用单线程分析(因为多模块并行编译已利用多核),但是目前的并发容忍设计为未来的多线程分析奠定了基础,后续 Kotlin Analysis API 可无缝适配。

而在插件迁移适配上,Kotlin Analysis API 也起到了很大作用,它封装了所有复杂的解析逻辑,并提供具有清晰且可预测行为的记录抽象,开发者只需请求他需要的语义代码信息片段,API 会处理所有延迟和并行分析并缓存结果。

例如要获取表达式类型,开发者只需调用库提供的 KtExpression.expressionType 扩展属性 ,如果类型尚不清楚,则将自动分析包含声明的 body :

kotlin
代码解读
复制代码
fun KtExpression.hasStringType(): Boolean { analyze(this) { return expressionType == builtinTypes.string } }

而事实上,不管你的项目是不是 K2 ,都可以享受到新 IDE 在 K2 模式下带来的性能提升,而如果你开发或使用的是插件,那么可能会需要将部分依赖旧的 Kotlin 插件进行迁移,例如:

  • 旧的编译器 API
kotlin
代码解读
复制代码
SPECIAL_ANNOTATION_NAME = FqName("my.app.Special") fun hasAnnotation(declaration: KtDeclaration): Boolean { val bindingContext = declaration.analyze() val descriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration] ?: return false return descriptor.annotations.hasAnnotation(SPECIAL_ANNOTATION_NAME) }
  • 新 Analysis API
kotlin
代码解读
复制代码
val SPECIAL_ANNOTATION_CLASS_ID = ClassId.fromString("my/app/Special") fun hasAnnotation(declaration: KtDeclaration): Boolean { analyze(declaration) { return SPECIAL_ANNOTATION_CLASS_ID in declaration.symbol.annotations } }

另外,就像前面说的,关于一些新特性,比如 Kotlin 2.1 的新支持就会仅限于 K2 模式的 IDE,例如:

  • Non-local 的 break/continue :
kotlin
代码解读
复制代码
fun processList(elements: List<Int>): Boolean { for (element in elements) { val variable = element.nullableMethod() ?: run { log.warning("Element is null or invalid, continuing...") continue // 在早期不能在 forEach 的 lambda 中直接使用 continue } if (variable == 0) return true // If variable is zero, return true } return false }
  • 在 when 里使用 guard condition:
kotlin
代码解读
复制代码
sealed interface Animal { data class Cat(val mouseHunter: Boolean) : Animal { fun feedCat() {} } data class Dog(val breed: String) : Animal { fun feedDog() {} } } fun feedAnimal(animal: Animal) { when (animal) { // Branch with only the primary condition. Returns `feedDog()` when `Animal` is `Dog` is Animal.Dog -> animal.feedDog() // Branch with both primary and guard conditions. Returns `feedCat()` when `Animal` is `Cat` and is not `mouseHunter` is Animal.Cat if !animal.mouseHunter -> animal.feedCat() // Returns "Unknown animal" if none of the above conditions match else -> println("Unknown animal") } }
  • 多美元字符串插值,通过初始 $$ 表示需要两个美元符号 ($$) 来触发插值,防止 $schema、$id 和 $dynamicAnchor 被解释为插值标记:
kotlin
代码解读
复制代码
val KClass<*>.jsonSchema : String get() = $$""" { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://example.com/product.schema.json", "$dynamicAnchor": "meta" "title": "$${simpleName ?: qualifiedName ?: "unknown"}", "type": "object" } """

最后,未来即将更新的 Android Studio 也会一样默认开始 K2 模式,所以作为 Android 开发,对于下一个版本的 AS 更新还需要慎重,因为你也不知道会有什么坑在等着你。

当然,最后还是要强调:

  • K2 编译器是 Kotlin 语言的新一代编译器
  • K2 Mode 是 IntelliJ IDEA 的一种运行模式

K2 Mode 是 IDEA 利用 K2 编译器的前端(解析和语义分析部分)来增强 IDE 的 Kotlin 代码理解能力,但不直接参与项目的实际编译,功能范围仅限于 IDE 的交互体验。

所以理论上,你项目用 K1,也不影响你体验 K2 Mode ,但是如果你项目使用 K2,那么强烈建议开始 K2 Mode 来体验全新的特性。

那么,你已经体验过 K2 模式了么?

参考资料

  • blog.jetbrains.com/idea/2025/0…

  • blog.jetbrains.com/idea/2025/0…

注:本文转载自juejin.cn的恋猫de小郭的文章"https://juejin.cn/post/7493912833991557131"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

140
Android
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top