一次搞懂:Gradle 运行时 JDK 与项目 compileOptions 中的 Java 版本有什么区别?
前言
在开发 Android 应用时,不少开发者都遇到过这样一个诡异的错误:
text
Unsupported class file major version 64
明明自己在build.gradle中写的compileOptions是 Java 8,可为什么 Gradle 非要报一个 Java 20 的错误?两者之间到底有什么关系?
今天我们就来彻底理清这两个“Java 版本”的区别,并解决由此引发的构建失败问题。
一、两个“Java 版本”的概念
在 Android 项目中,存在两个完全不同的 Java 版本概念:
1. Gradle 运行时 JDK 版本
它是什么?
Gradle 本身是用 Java 编写的构建工具。当你执行./gradlew build时,Gradle 会启动一个 Java 进程来完成构建工作。这个进程所使用的 JDK 版本,就是Gradle 运行时 JDK 版本。如何查看?
在项目根目录下运行:./gradlew --version
输出的第一行JVM后面的版本号就是这个值。它决定什么?
决定了 Gradle 能否正常启动。如果 Gradle 版本太老,不支持当前 JDK 版本(比如 Gradle 7.0.2 不支持 Java 20),就会直接报错退出。
2. 项目的compileOptions中的 Java 版本
它是什么?
在模块的build.gradle文件中,通过compileOptions配置的sourceCompatibility和targetCompatibility,用于指定项目源代码的语言级别以及生成的字节码兼容的最低 Java 版本。示例配置:
android { compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }它决定什么?
决定了你可以使用哪些 Java 语法特性(如 Lambda、Stream API),以及生成的字节码能在多老的 JVM 上运行。它完全不控制Gradle 运行时使用的 JDK 版本。
二、两者之间的关系
简单说:没有直接关系。
Gradle 运行时 JDK 是工人手里的机器—— 它只需要满足 Gradle 版本的要求即可。
项目的
compileOptions是产品规格书—— 它规定最终 APK 内的代码兼容级别。
你完全可以:
用 JDK 17 运行 Gradle
但要求编译出的代码兼容 Java 8
这是完全合法且常见的做法。反之,即使你设置了sourceCompatibility = 1.8,如果你用 Java 20 去运行一个老旧的 Gradle 7.0.2,依然会崩溃,因为Gradle 自身不认 Java 20。
三、常见错误场景
| 错误现象 | 根本原因 |
|---|---|
Unsupported class file major version 64 | Gradle 运行时 JDK 是 Java 20(major 64),而当前 Gradle 版本(如 7.0.2)最高只支持到 Java 17。 |
Unsupported class file major version 61 | 运行时 JDK 是 Java 17,但 Gradle 版本太老(如 6.x)。 |
| 编译时提示 Lambda 表达式不支持 | sourceCompatibility未设置为 1.8 或更高。 |
四、如何解决?
方案一:降低 Gradle 运行时 JDK 版本(推荐,改动最小)
在 Android Studio 中,点击
File→Project Structure→SDK Location。在
Gradle Settings部分,将Gradle JDK改为JDK 11或JDK 17。点击
OK,然后重新同步项目。
注意:JDK 17 是目前最稳妥的选择,Gradle 7.x 和 8.x 都完美支持。
方案二:升级 Gradle 版本(如果必须使用高版本 JDK)
如果因为某些原因(例如团队统一要求)你非要用 Java 20 来运行 Gradle,那么就需要升级 Gradle 到支持 Java 20 的版本。
| Gradle 版本 | 最高支持 Java 版本 |
|---|---|
| 7.0 ~ 7.4 | Java 17 |
| 7.5 ~ 7.6.x | Java 19 |
| 8.3+ | Java 20 |
修改gradle/wrapper/gradle-wrapper.properties:
properties
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip
然后同步项目。
注意:从 Gradle 7.x 升级到 8.x 可能会遇到其他废弃 API 的兼容问题,需要额外处理。
五、总结
Gradle 运行时 JDK:负责启动 Gradle 进程,其版本必须被 Gradle 版本所支持。
compileOptions中的 Java 版本:只影响项目源码的编译规则和字节码兼容性,与 Gradle 运行时无关。最佳实践:
将 Gradle JDK 设置为JDK 17(稳定且广泛支持)。
将
compileOptions设置为JavaVersion.VERSION_1_8(兼容绝大多数 Android 设备)。如果确实需要 Java 11/17 的语言特性,再相应升级
sourceCompatibility,同时确保minSdkVersion足够高。
希望这篇文章能帮你彻底厘清这两个容易混淆的 Java 版本概念,从此不再被Unsupported major version所困扰。
如果你有更多关于 Android 构建配置的问题,欢迎在评论区留言讨论。
