13.6.2.3 Kotlin 2.2.x 兼容性指南
13 分钟阅读
原文链接: https://kotlinlang.org/docs/compatibility-guide-22.html
13.6.2.3 Kotlin 2.2.x 兼容性指南
保持语言的现代性 和 舒适的更新 是 Kotlin 语言设计中的基本原则。前者指出,阻碍语言演进的构造应该被移除;后者指出,这种移除应事先充分沟通,以便代码迁移尽可能顺畅。
虽然大多数语言变更已经通过其他渠道公布过(例如更新日志或编译器警告),但本文汇总了所有这些变更,为从 Kotlin 2.1 迁移到 Kotlin 2.2 提供完整参考。
基本术语
本文介绍了以下几种兼容性:
- 源码级:源码不兼容的变更会让原本能正常编译(无错误或警告)的代码不再能编译
- 二进制级:如果互换两个二进制产物不会导致加载或链接错误,则称它们是二进制兼容的
- 行为级:如果同一个程序在应用变更前后的行为不同,则该变更属于行为不兼容
请记住,这些定义仅针对纯 Kotlin。从其他语言(例如 Java)的视角来看 Kotlin 代码的兼容性不在本文讨论范围内。
语言
放弃对 1.6 和 1.7 的 -language-version 支持
Issue:KT-71793 组件:编译器 不兼容变更类型:源码级 简要说明:从 Kotlin 2.2 开始,编译器不再支持
-language-version=1.6或-language-version=1.7。这意味着不再支持早于 1.8 的语言特性集。不过,语言本身仍与 Kotlin 1.0 完全向后兼容。弃用周期:- 2.1.0:使用-language-version指定 1.6 和 1.7 版本时报告警告 - 2.2.0:使用-language-version指定 1.8 和 1.9 版本时报告警告;把 1.6 和 1.7 的警告提升为错误
默认为带注解的 lambda 启用 invokedynamic
Issue:KTLC-278 组件:核心语言 不兼容变更类型:行为级 简要说明:带注解的 lambda 现在默认通过
LambdaMetafactory使用invokedynamic,其行为与 Java lambda 保持一致。这会影响依赖从生成的 lambda 类中获取注解的反射代码。要回退到旧行为,请使用-Xindy-allow-annotated-lambdas=false编译器选项。弃用周期:- 2.2.0:默认为带注解的 lambda 启用invokedynamic
在 K2 中禁止对展开类型带型变的类型别名进行构造器调用和继承
Issue:KTLC-4 组件:核心语言 不兼容变更类型:源码级 简要说明:对于展开为使用
out等型变修饰符的类型的类型别名,K2 编译器不再支持对其进行构造器调用和继承。这解决了这样的不一致:直接使用原类型不被允许,而通过类型别名进行同样的使用却被允许。要迁移,请在需要的地方显式使用原类型。弃用周期:- 2.0.0:对展开为带型变修饰符类型的类型别名上的构造器调用或父类型用法报告警告 - 2.2.0:把该警告提升为错误
禁止从 Kotlin getter 生成合成属性
Issue:KTLC-272 组件:核心语言 不兼容变更类型:源码级 简要说明:对于在 Kotlin 中定义的 getter,不再允许生成合成属性。这会影响 Java 类继承 Kotlin 类的情况,以及处理
java.util.LinkedHashSet等映射类型的情况。要迁移,请把属性访问替换为直接调用相应的 getter 函数。弃用周期:- 2.0.0:对访问由 Kotlin getter 生成的合成属性报告警告 - 2.2.0:把该警告提升为错误
修改 JVM 上接口函数默认方法的生成方式
Issue:KTLC-269 组件:核心语言 不兼容变更类型:二进制级 简要说明:接口中声明的函数现在会被编译为 JVM 默认方法,除非另有配置。当无关的父类型定义了冲突的实现时,这可能导致 Java 代码出现编译错误。该行为由稳定的
-jvm-default编译器选项控制,它取代了现已弃用的-Xjvm-default选项。要恢复之前的行为(仅在DefaultImpls类和子类中生成默认实现),请使用-jvm-default=disable。弃用周期:- 2.2.0:-jvm-default编译器选项默认设置为enable
禁止在注解属性上使用以字段为目标的注解
Issue:KTLC-7 组件:核心语言 不兼容变更类型:源码级 简要说明:注解属性上不再允许使用以字段为目标的注解。虽然这些注解没有任何可观察的效果,但该变更可能影响依赖它们的自定义 IR 插件。要迁移,请从该属性上移除以字段为目标的注解。弃用周期:- 2.1.0:注解属性上的
@JvmField注解被弃用并给出警告 - 2.1.20:对注解属性上的所有以字段为目标的注解报告警告 - 2.2.0:把该警告提升为错误
禁止在类型别名中使用 reified 类型参数
Issue:KTLC-5 组件:核心语言 不兼容变更类型:源码级 简要说明:类型别名中的类型参数不再允许使用
reified修饰符。reified 类型参数只在内联函数中有效,因此在类型别名中使用它们没有效果。要迁移,请从typealias声明中移除reified修饰符。弃用周期:- 2.1.0:对类型别名中的 reified 类型参数报告警告 - 2.2.0:把该警告提升为错误
修正内联值类在 Number 和 Comparable 上的类型检查
Issue:KTLC-21 组件:Kotlin/JVM 不兼容变更类型:行为级 简要说明:在
is和as检查中,内联值类不再被视为java.lang.Number或java.lang.Comparable的实现者。当应用于装箱的内联类时,这些检查此前会返回不正确的结果。该优化现在只适用于原始类型及其包装类。弃用周期:- 2.2.0:启用新行为
禁止来自间接依赖的不可访问泛型类型
Issue:KTLC-3 组件:核心语言 不兼容变更类型:源码级 简要说明:当使用编译器不可见的间接依赖中的类型时,K2 编译器现在会报告错误。这会影响 lambda 参数或泛型类型实参等情况,即由于缺少依赖而无法获得所引用的类型。弃用周期:- 2.0.0:对 lambda 中不可访问的泛型类型以及某些不可访问泛型类型实参的用法报告错误;对 lambda 中不可访问的非泛型类型以及表达式类型和父类型中不可访问的类型实参报告警告 - 2.1.0:把 lambda 中不可访问非泛型类型的警告提升为错误 - 2.2.0:把表达式类型中不可访问类型实参的警告提升为错误
对类型参数边界实施可见性检查
Issue:KTLC-274 组件:核心语言 不兼容变更类型:源码级 简要说明:函数和属性不再能使用可见性比该声明本身更严格的类型参数边界。这防止了间接触及不可访问的类型;此前这类代码能正常编译,但在某些情况下会导致运行时失败或 IR 校验错误。弃用周期:- 2.1.0:当类型参数的边界在声明的可见性作用域内不可见时报告警告 - 2.2.0:把该警告提升为错误
在非私有内联函数中暴露私有类型时报告错误
Issue:KT-70916 组件:核心语言 不兼容变更类型:源码级 简要说明:不再允许从非私有内联函数访问私有类型、函数或属性。要迁移,可以避免引用私有实体、把该函数改为私有,或者移除
inline修饰符。请注意,移除inline会破坏二进制兼容性。弃用周期:- 2.2.0:从非私有内联函数访问私有类型或成员时报告错误
禁止在作为参数默认值的 lambda 中使用非局部 return
Issue:KTLC-286 组件:核心语言 不兼容变更类型:源码级 简要说明:在作为参数默认值使用的 lambda 中,不再允许使用非局部 return 语句。这种写法以前能够编译,但会导致运行时崩溃。要迁移,请改写该 lambda 以避免非局部 return,或把逻辑移到默认值之外。弃用周期:- 2.2.0:对作为参数默认值使用的 lambda 中的非局部 return 报告错误
标准库
弃用 kotlin.native.Throws
Issue:KT-72137 组件:Kotlin/Native 不兼容变更类型:源码级 简要说明:
kotlin.native.Throws已被弃用;请改用公共的kotlin.Throws注解。弃用周期:- 1.9.0:使用kotlin.native.Throws时报告警告 - 2.2.0:把该警告提升为错误
弃用 AbstractDoubleTimeSource
Issue:KT-72137 组件:kotlin-stdlib 不兼容变更类型:源码级 简要说明:
AbstractDoubleTimeSource已被弃用;请改用AbstractLongTimeSource。弃用周期:- 1.8.20:使用AbstractDoubleTimeSource时报告警告 - 2.2.0:把该警告提升为错误
工具
修正 KotlinCompileTool 中的 setSource() 函数以替换源
Issue:KT-59632 组件:Gradle 不兼容变更类型:行为级 简要说明:
KotlinCompileTool接口中的setSource()函数现在会替换已配置的源,而不是追加到它们。如果你想在不替换现有源的情况下添加源,请使用source()函数。弃用周期:- 2.2.0:启用新行为
弃用 KotlinCompilationOutput#resourcesDirProvider 属性
Issue:KT-70620 组件:Gradle 不兼容变更类型:源码级 简要说明:
KotlinCompilationOutput#resourcesDirProvider属性已被弃用。请改为在 Gradle 构建脚本中使用KotlinSourceSet.resources来添加额外的资源目录。弃用周期:- 2.1.0:KotlinCompilationOutput#resourcesDirProvider被弃用并给出警告 - 2.2.0:把该警告提升为错误
弃用 BaseKapt.annotationProcessorOptionProviders 属性
Issue:KT-58009 组件:Gradle 不兼容变更类型:源码级 简要说明:
BaseKapt.annotationProcessorOptionProviders属性已被弃用,改用BaseKapt.annotationProcessorOptionsProviders,后者接受ListProperty<CommandLineArgumentProvider>而不是MutableList<Any>。这明确规定了期望的元素类型,并防止因添加错误元素(例如嵌套列表)而导致的运行时失败。如果你当前的代码把列表作为单个元素添加,请把add()函数替换为addAll()函数。弃用周期:- 2.2.0:在 API 中强制使用新类型
弃用 kotlin-android-extensions 插件
Issue:KT-72341 组件:Gradle 不兼容变更类型:源码级 简要说明:
kotlin-android-extensions插件已被弃用。请改用单独的插件kotlin-parcelize来生成Parcelable实现,并用 Android Jetpack 的视图绑定来替代合成视图。弃用周期:- 1.4.20:该插件被弃用 - 2.1.20:引入配置错误,且不再执行任何插件代码 - 2.2.0:移除插件代码 - 2.4.0:移除该插件 ID
弃用 kotlinOptions DSL
Issue:KT-54110 组件:Gradle 不兼容变更类型:源码级 简要说明:通过
kotlinOptionsDSL 以及相关的KotlinCompile<KotlinOptions>任务接口配置编译器选项的能力已被弃用,改用新的compilerOptionsDSL。作为该弃用的一部分,kotlinOptions接口中的所有属性现在也都被单独标记为已弃用。要迁移,请使用compilerOptionsDSL 配置编译器选项。迁移指南请参阅从kotlinOptions {}迁移到compilerOptions {}。弃用周期:- 2.0.0:对kotlinOptionsDSL 报告警告 - 2.2.0:把该警告提升为错误,并弃用kotlinOptions中的所有属性
移除 kotlin.incremental.useClasspathSnapshot 属性
Issue:KT-62963 组件:Gradle 不兼容变更类型:源码级 简要说明:
kotlin.incremental.useClasspathSnapshotGradle 属性已被移除。该属性用于控制已弃用的基于历史的 JVM 增量编译模式,后者自 Kotlin 1.8.20 起已被默认启用的基于 classpath 的方式取代。弃用周期:- 2.0.20:以警告形式弃用kotlin.incremental.useClasspathSnapshot属性 - 2.2.0:移除该属性
Kotlin 脚本相关的弃用
Issues:KT-71685、KT-75632、KT-76196。组件:脚本 不兼容变更类型:源码级 简要说明:Kotlin 2.2.0 弃用了对以下内容的支持:* REPL:要继续通过
kotlinc使用 REPL,请使用-Xrepl编译器选项来选择启用。* JSR-223:因为该 JSR 处于 Withdrawn(已撤回)状态。JSR-223 实现仍可在语言版本 1.9 下工作,但未来没有迁移到 K2 编译器的计划。*KotlinScriptMojoMaven 插件。如果你继续使用它,会看到编译器警告。更多信息请参阅我们的博客文章。弃用周期:- 2.1.0:以警告形式弃用kotlinc中 REPL 的使用 - 2.2.0:要通过kotlinc使用 REPL,请用-Xrepl编译器选项选择启用;弃用 JSR-223,切换到语言版本 1.9 可以恢复支持;弃用KotlinScriptMojoMaven 插件 - 2.4.0:移除通过KotlinScriptMojoMaven 插件执行 Kotlin 脚本的能力
弃用消歧分类器属性
Issue:KT-58231 组件:Gradle 不兼容变更类型:源码级 简要说明:用于控制 Kotlin Gradle 插件如何对源集名称和 IDE 导入进行消歧的选项已经过时。因此,
KotlinTarget接口中的以下属性现已被弃用:*useDisambiguationClassifierAsSourceSetNamePrefix*overrideDisambiguationClassifierOnIdeImport弃用周期:- 2.0.0:使用这些 Gradle 属性时报告警告 - 2.1.0:把该警告提升为错误 - 2.2.0:移除这些 Gradle 属性
弃用 commonization 参数
Issue:KT-75161 组件:Gradle 不兼容变更类型:源码级 简要说明:Kotlin Gradle 插件中用于实验性 commonization 模式的参数已被弃用。这些参数可能产生无效的编译产物并被缓存。要删除受影响的产物:1. 从
gradle.properties文件中移除以下选项:none kotlin.mpp.enableOptimisticNumberCommonization kotlin.mpp.enablePlatformIntegerCommonization2. 清理~/.konan/*/klib/commonized目录中的 commonization 缓存,或运行以下命令:bash ./gradlew cleanNativeDistributionCommonization弃用周期:- 2.2.0:以错误形式弃用 commonization 参数 - 2.2.20:移除 commonization 参数
弃用对旧式元数据编译的支持
Issue:KT-61817 组件:Gradle 不兼容变更类型:源码级 简要说明:用于设置分层结构以及在公共源集与中间源集之间创建中间源集的选项已经过时。以下编译器选项已被移除:*
isCompatibilityMetadataVariantEnabled*withGranularMetadata*isKotlinGranularMetadataEnabled弃用周期:- 2.2.0:从 Kotlin Gradle 插件中移除这些编译器选项
弃用 KotlinCompilation.source API
Issue:KT-64991 组件:Gradle 不兼容变更类型:源码级 简要说明:
KotlinCompilation.sourceAPI 的访问已被弃用,该 API 曾允许把 Kotlin 源集直接添加到 Kotlin 编译中。弃用周期:- 1.9.0:使用KotlinCompilation.source时报告警告 - 1.9.20:把该警告提升为错误 - 2.2.0:从 Kotlin Gradle 插件中移除KotlinCompilation.source;尝试使用它会在构建脚本编译期间导致 “unresolved reference” 错误
弃用目标预设 API
Issue:KT-71698 组件:Gradle 不兼容变更类型:源码级 简要说明:Kotlin Multiplatform 目标的目标预设已经过时;
jvm()或iosSimulatorArm64()等目标 DSL 函数现在覆盖了相同的使用场景。所有与预设相关的 API 都已被弃用:*org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension中的presets属性 *org.jetbrains.kotlin.gradle.plugin.KotlinTargetPreset接口及其所有继承者 *fromPreset的各重载 弃用周期:- 1.9.20:对任何使用预设相关 API 的地方报告警告 - 2.0.0:把该警告提升为错误 - 2.2.0:从 Kotlin Gradle 插件的公共 API 中移除预设相关 API;仍然使用它的源码会因 “unresolved reference” 错误而失败,二进制文件(例如 Gradle 插件)如果不针对最新版本的 Kotlin Gradle 插件重新编译,可能会出现链接错误
弃用 Apple 目标快捷方式
Issue:KT-70615 组件:Gradle 不兼容变更类型:源码级 简要说明:Kotlin Multiplatform DSL 中的
ios()、watchos()和tvos()目标快捷方式已被弃用。这些快捷方式原本用于为 Apple 目标部分创建源集层级。Kotlin Multiplatform Gradle 插件现在提供了内置的层级模板。请改为指定目标列表,插件会自动为它们设置中间源集。弃用周期:- 1.9.20:使用目标快捷方式时报告警告;改为默认启用默认层级模板 - 2.1.0:使用目标快捷方式时报告错误 - 2.2.0:从 Kotlin Multiplatform Gradle 插件中移除目标快捷方式 DSL
弃用 publishAllLibraryVariants() 函数
Issue:KT-60623 组件:Gradle 不兼容变更类型:源码级 简要说明:
publishAllLibraryVariants()函数已被弃用。它原本用于发布 Android 目标的所有构建变体。现在不再推荐这种做法,因为它可能导致变体解析出问题,尤其是在使用多个 flavor 和构建类型时。请改用指定构建变体的publishLibraryVariants()函数。弃用周期:- 2.2.0:publishAllLibraryVariants()被弃用
弃用 android 目标
Issue:KT-71608 组件:Gradle 不兼容变更类型:源码级 简要说明:当前 Kotlin DSL 中的
android目标名称已被弃用。请改用androidTarget。弃用周期:- 1.9.0:在 Kotlin Multiplatform 项目中使用android名称时引入弃用警告 - 2.1.0:把该警告提升为错误 - 2.2.0:从 Kotlin Multiplatform Gradle 插件中移除android目标 DSL
弃用 CInteropProcess 中的 konanVersion
Issue:KT-71069 组件:Gradle 不兼容变更类型:源码级 简要说明:
CInteropProcess任务中的konanVersion属性已被弃用。请改用CInteropProcess.kotlinNativeVersion。弃用周期:- 2.1.0:使用konanVersion属性时报告警告 - 2.2.0:把该警告提升为错误 - 2.3.0:从 Kotlin Gradle 插件中移除konanVersion属性
弃用 CInteropProcess 中的 destinationDir
Issue:KT-71068 组件:Gradle 不兼容变更类型:源码级 简要说明:
CInteropProcess任务中的destinationDir属性已被弃用。请改用CInteropProcess.destinationDirectory.set()函数。弃用周期:- 2.1.0:使用destinationDir属性时报告警告 - 2.2.0:把该警告提升为错误 - 2.3.0:从 Kotlin Gradle 插件中移除destinationDir属性
弃用 kotlinArtifacts API
Issue:KT-74953 组件:Gradle 不兼容变更类型:源码级 简要说明:实验性的
kotlinArtifactsAPI 已被弃用。请使用 Kotlin Gradle 插件中现有的 DSL 来构建最终的本地二进制文件。如果这不足以完成迁移,请在这个 YouTrack issue 中留言。弃用周期:- 2.2.0:使用kotlinArtifactsAPI 时报告警告 - 2.3.0:把该警告提升为错误