Android项目中kotlinOptions.jvmTarget必须在android{}块内配置,值为字符串如"1.8",且需与compileOptions的source/targetCompatibility严格一致,否则D8/R8构建失败;多模块需逐个配置。

build.gradle.kts 里怎么设 kotlinOptions.jvmTarget
必须在 android {} 块内配置,不是项目根目录的 kotlinOptions(那是 JVM 后端用的)。Android 项目中,Kotlin 字节码目标版本由 Android 插件控制,写错位置会导致设置被忽略。
正确写法示例:
android {
compileSdk = 34
kotlinOptions {
jvmTarget = "1.8" // 或 "11"、"17",需与 compileOptions 对齐
freeCompilerArgs += "-Xjvm-default=all"
}
}
-
jvmTarget决定 Kotlin 编译出的 class 文件的 major version(如"1.8"→ 52,"17"→ 61) - 值必须是字符串,不能写
JavaVersion.VERSION_1_8—— 那是 Java 的写法,Kotlin 不认 - 如果用了 KSP(
kspDebugKotlin),它会直接读这个值;KAPT 则依赖它生成 stubs,不一致就会报Inconsistent JVM-target compatibility
为什么 compileOptions 和 kotlinOptions.jvmTarget 必须一致
二者控制不同语言产出的字节码版本,但最终要交给 D8/R8 合并处理。一旦 mismatch(比如 Java 编译成 52,Kotlin 编译成 61),D8 无法安全做 desugar 或优化,构建直接失败。
常见错误现象:
Execution failed for task ':app:kaptGenerateStubsDebugKotlin''compileDebugJavaWithJavac' (1.8) and 'kspDebugKotlin' (17) jvm target compatibility should be set to the same Java version
对应配置必须同步:
android {
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
选 1.8 还是 11/17?看 AGP 和运行时兼容性
不是越高越好。Android 上 jvmTarget = "17" 要求 AGP ≥ 8.3、D8 ≥ 8.3,且部分旧设备上 invokedynamic 等指令可能触发 VerifyError。
- 生产项目推荐
"1.8":兼容所有 Android 5.0+,与 desugar 配合最稳 - 仅当明确需要 Java 11+ 语言特性(如
var在局部变量推导外的扩展)且已升级 AGP ≥ 8.3 时,才考虑"11"或"17" -
sourceCompatibility和jvmTarget可以不同(例如 Java 写 11 特性但输出 1.8 字节码),但 Kotlin 不支持这种“降级编译”,jvmTarget是硬约束
多模块项目里容易漏掉的地方
每个带 Kotlin 源码的 module 都要单独配 kotlinOptions.jvmTarget。父项目的配置不会继承给子 module —— 尤其是 :core、:feature 这类独立编译的模块。
如果你在 :app 里配了,但 :data 模块没配,而 :data 又被 :app 依赖,那么 kspDataKotlin 任务仍会用默认值(通常是 JDK 主版本),导致和 :app 的 jvmTarget 冲突。
建议统一写在 subprojects 闭包里(适用于 build.gradle.kts):
subprojects {
plugins.withId("org.jetbrains.kotlin.android") {
configure<org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension> {
jvmToolchain(8) // 更现代的写法,自动对齐 source/target/jvmTarget
}
}
}
注意:jvmToolchain 是 Gradle 17+ 推荐方式,但 Android Gradle Plugin 当前(AGP 8.6)对其支持仍有限,实际生效仍依赖显式 jvmTarget。别只信 toolchain,该写的 jvmTarget 一行不能少。


















