Project SDK仅作全局兜底,Module SDK才真正决定模块编译行为、语言特性和字节码版本;两者不一致会导致隐蔽性错误如NoClassDefFoundError或编辑器标红与编译结果不符,须逐模块手动设置SDK并重载项目。

Project SDK 是项目级的默认 JDK,只起全局兜底作用;Module SDK 才真正决定每个模块的编译行为、语言特性和字节码版本。
Project SDK:全局默认值,不直接控制编译
它定义整个项目的默认开发套件,影响新模块创建时的初始 SDK 选择,但本身不参与具体模块的编译决策。即使 Project SDK 设为 JDK 21,某个模块若单独配置了 JDK 11 的 Module SDK,该模块就只能用 11 的语法和 API——IDE 和编译器都以 Module SDK 为准。
- 修改 Project SDK 不会自动更新已有模块的 SDK
- 新建模块默认继承 Project SDK,但继承后仍可单独覆盖
- 它不决定字节码版本,也不影响依赖解析范围
Module SDK:模块真实运行与编译依据
每个模块独立拥有自己的 Module SDK,优先级高于 Project SDK。IDE 编译、语法高亮、代码补全、错误提示(如 cannot resolve symbol)全部基于此设置。比如子模块配了 JDK 11,却用了 JDK 17 的 sealed 关键字,就会标红,哪怕 Project SDK 是 17。
- 多模块项目中,不同模块可设不同 JDK(如兼容旧模块用 8,新功能模块用 17)
- Gradle 或 Maven 同步后,Module SDK 可能被重置为 Project SDK,需手动确认
- 若显示 None,表示继承 Project SDK,但语言级别仍需单独检查是否匹配
两者不一致的典型后果
不是报错“JDK 版本不匹配”,而是表现得更隐蔽:
- 编辑器里语法正常(因 Project SDK 提供了高版本提示),但编译失败或运行时报 NoClassDefFoundError
- 使用 var、record、switch 表达式等特性时,仅部分模块标红,定位困难
- Gradle 命令行构建成功,IDE 内却报错,或反之
- 打包后在目标环境启动失败,日志显示 Unsupported major.minor version xx.0
怎么查和统一才可靠
别只看 pom.xml 或 build.gradle 里的 <java.version>,IDEA 不自动同步这些声明:
- 进 File → Project Structure → Project 看 Project SDK
- 再逐个点开 Modules → [模块名] → Dependencies 查 Module SDK
- 每个模块务必手动选具体版本,不要选 Inherit project SDK
- 同步改完后,执行 Reload project(Gradle)或 Reload project from Disk(Maven)


















