
Gradle插件版本决定了能用的JDK上限
Android Studio 不是“随便选个 JDK 就能编译”,com.android.tools.build:gradle(AGP)版本有明确的 JDK 兼容范围。比如 AGP 8.0+ 要求 JDK 17,但不支持 JDK 21;AGP 8.4 开始才正式支持 JDK 21。用高了或低了都会报错——最常见的是 Unsupported class file major version 或 Could not determine java version from '21.0.1'。
- 查当前 AGP 版本:看项目根目录
build.gradle(或build.gradle.kts)里dependencies { classpath 'com.android.tools.build:gradle:x.y.z' } - 查兼容表:直接去 AGP 官方兼容页,别猜
- AGP 8.2 默认用 JDK 17,但允许你配 JDK 21 —— 前提是 AGP ≥ 8.4,且
android.compileSdk≥ 34
在 gradle.properties 里设 org.gradle.java.home 是最稳的方式
很多人改 Android Studio 的 SDK 配置(File → Project Structure → SDK Location),但这只影响 IDE 自身运行和代码提示,不控制 Gradle 编译任务。真正起作用的是 Gradle 进程启动时用的 JDK,必须靠 org.gradle.java.home 指定。
- 打开项目根目录下的
gradle.properties - 加一行:
org.gradle.java.home=/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home(macOS)或org.gradle.java.home=C:\Program Files\Java\jdk-17.0.1(Windows) - 路径必须指向 JDK 根目录,不是
bin子目录,也不是 JRE - 改完后必须重启 Android Studio 或执行
./gradlew --stop清掉旧 Gradle daemon,否则缓存会继续用错 JDK
模块级 build.gradle 里的 javaVersion 只管源码兼容性
android { compileOptions { sourceCompatibility JavaVersion.VERSION_17; targetCompatibility JavaVersion.VERSION_17 } } 这段配置,只告诉编译器“允许你写 JDK 17 的语法(比如 var、密封类),生成的字节码也按 17 格式打”。它不决定用哪个 JDK 执行编译——那是 org.gradle.java.home 的事。
- 如果
sourceCompatibility设成VERSION_21,但org.gradle.java.home指向 JDK 17,会直接报错:error: release version 21 not supported - 反过来,
org.gradle.java.home指向 JDK 21,但sourceCompatibility还是VERSION_17,那你能用record、switch表达式等新语法,但编译器不会校验 JDK 21 特性(比如虚拟线程) - 推荐保持三者一致:AGP 版本 → 支持的 JDK →
org.gradle.java.home→source/targetCompatibility
遇到 Failed to initialize compiler 或 Could not find tools.jar 怎么办
这两个错误基本等于 Gradle 找到了一个“假 JDK”——比如你装的是 JRE,或者 JDK 安装不完整(尤其是从 Oracle 下载的旧版 JDK,可能缺 tools.jar),又或者路径里有空格、中文、符号。
- 验证 JDK 是否有效:终端执行
$JAVA_HOME/bin/java -version和$JAVA_HOME/bin/javac -version,两个都得成功输出 - Mac 用户特别注意:系统自带的
/usr/libexec/java_home返回的路径可能指向 JRE,要用/usr/libexec/java_home -v 17显式指定版本 - Windows 用户避免用 Program Files 路径,优先选解压版 JDK(如 Temurin),放在
C:devjdk-17这类无空格路径下 - Android Studio 内置 JDK(
Android Studio.app/Contents/jbr)只供 IDE 使用,不要设给org.gradle.java.home,它没打包javac
最麻烦的其实是多模块项目里不同 module 用了不同 sourceCompatibility,而整个项目却只配了一个 JDK——这时不是编译失败,而是行为不一致:某个 module 用了 Stream.toList()(JDK 16+),但另一个 module 的依赖却在 JDK 17 下编译出 class 文件,运行时报 NoSuchMethodError。这种问题不会在 build 阶段暴露,得靠运行时排查。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











