用途
本技能为不绑定特定框架的 Java 项目提供日常开发指导。如果项目使用 Spring Boot、Quarkus、Helidon 或类似框架,框架相关问题应优先使用该框架对应的技能,本技能用于处理其中的纯 Java 部分。
始终适用的规则
- 先检测再编写:阅读 pom.xml/build.gradle*、.mvn/、gradle/、.java-version/.sdkmanrc、.editorconfig、CI 文件以及若干源文件,匹配项目已有的构建工具、Java 版本、格式化器、命名、日志与测试库。
- 绝不隐式升级:不要因为其他任务而顺带更改 Java 版本、构建工具版本、插件或依赖版本,也不要添加项目原本没有的格式化器/检查器/静态分析器。应提出建议并询问。版本升级是独立任务(如已安装 java-upgrade)。
- 存在 wrapper(./mvnw、./gradlew)时使用 wrapper,否则使用已安装的 mvn/gradle。不要未经要求就提交 wrapper。
- 用构建验证:任何改动后运行项目自身的验证命令(./mvnw -B verify 或 ./gradlew build)并报告结果。迭代时可先运行更窄的命令。若无法运行,需说明。
- 以下情况先询问用户:更改公共 API 或序列化/数据库/传输格式、提升 Java 版本、添加运行时依赖、向构建中添加工具、删除或弱化测试、更改 CI,或两种合理设计存在不同权衡时。
- 优先使用标准库和少量显式代码,而非新增依赖。除非项目已使用,否则不要引入 Lombok。
按项目 Java 版本选择惯用法
检查 maven.compiler.release/<release>、java.toolchain 或 sourceCompatibility,绝不使用高于该版本的特性。
- 8:lambda、stream、Optional、java.time
- 11:var、String.isBlank/strip/lines、java.net.http.HttpClient、List.of/Map.of(9)
- 17:record、sealed 类、文本块、switch 表达式、instanceof 模式
- 21:switch 模式匹配、record 模式、虚拟线程、SequencedCollection(getFirst/getLast/reversed)
- 22-24:未命名变量 _(22)、Stream.gather(24)
- 25:scoped values、实例 main/紧凑源文件、模块导入声明(均为正式)
结构化并发(StructuredTaskScope)在 25 和 27 中仍是预览 API(已验证:需要 --enable-preview);除非用户明确选择启用预览特性,否则不要在生产代码中使用。
构建工具实践
- Maven:./mvnw -B verify(编译、单元测试、集成测试、打包),-pl <module> -am 针对单个模块,dependency:tree,仅在用户要求时使用 -DskipTests。
- Gradle:./gradlew build、test --tests 'pkg.Class'、dependencies、dependencyInsight --dependency <name>。
- 标准布局:src/main/java、src/main/resources、src/test/java、src/test/resources;按功能分包,每个文件一个顶层类型,不使用拆分包。
- 显式设置 Java 版本(maven.compiler.release / Gradle toolchain 配合 options.release)和 UTF-8 编码;不要依赖恰好运行构建的 JDK。
- wrapper、BOM 与 dependency:tree/versions 的用法、版本目录与多模块布局见 references/build-and-dependencies.md。
依赖与漏洞
- 导入 BOM(junit-bom、testcontainers-bom、框架的 BOM)而非重复版本;跨模块每个库只用一个版本。
- 更改前先检查:mvn dependency:tree -Dincludes=group:artifact / gradlew dependencyInsight。用 dependencyManagement 或 Gradle constraints 解决冲突,不要随意排除。
- 用 mvn versions:display-dependency-updates(加 -Dmaven.version.ignore 隐藏 alpha/beta/RC)检查更新并报告;未经询问不要应用大版本升级。
- 漏洞:使用项目已有的工具(Dependabot/Renovate 告警、OWASP dependency-check、OSV-Scanner、GitHub dependency review)。若没有可建议其一,但不要静默添加。扫描器配置中不要放密钥;基于 NVD 的扫描器需要 API key 才实用。
与版本相关的失败(已验证)
- JDK 23+ 不再隐式运行注解处理器(Lombok、MapStruct、Dagger 等):除非给出 -processor、--processor-path 或 --processor-module-path,否则 -proc:none 是默认值。需在构建中声明处理器路径(Maven annotationProcessorPaths、Gradle annotationProcessor)或传入 -proc:full。JDK 21+ 检测到隐式使用时会打印警告;-proc:full 也已向后移植到 17.0.11、11.0.23 和 8u411。来源:https://inside.java/2024/06/18/quality-heads-up/。
- 虚拟线程与 synchronized:在 JDK 21-23 上,虚拟线程在 synchronized 内阻塞会被固定到其载体线程;JEP 491 在 JDK 24+ 移除了几乎所有此类固定。在 21-23 上,阻塞调用周围优先使用 ReentrantLock。来源:https://openjdk.org/jeps/491。
- Error Prone 在 JDK 16+ 需要 --add-exports/--add-opens javac 标志,在 JDK 21 需要 -XDaddTypeAnnotationsToSymbol=true(见质量参考)。
- 绝不使用高于项目 release 的语言特性(见上表)。
静态分析与格式化(仅在已存在或用户同意时)
尊重已有配置:若项目使用 Spotless/Checkstyle/SpotBugs/Error Prone,运行它们并修复发现的问题;若没有,不要添加。被要求引入时,从 -Xlint:all 和 Spotless(仅格式化)开始,然后是 Error Prone。JDK 21 和 25 上 Maven 与 Gradle 的已验证配置(包括仅 JDK 21 需要的 -XDaddTypeAnnotationsToSymbol=true 以及 Maven .mvn/jvm.config 标志)见 references/quality-and-packaging.md。绝不在无关改动中重新格式化整个代码库。
打包与 CI
- 纯库 jar:mvn package/gradlew jar。可运行应用:shaded/fat jar 或 lib/ 目录加 manifest Main-Class;用 jlink 定制运行时;用 jpackage 生成原生安装包/app-image(已在 macOS 验证,见 references/quality-and-packaging.md)。
- GitHub Actions:actions/checkout、actions/setup-java 配合 distribution: temurin、显式 java-version、内置依赖缓存,然后 ./mvnw -B verify 或 ./gradlew build。片段与说明见 references/quality-and-packaging.md。未经询问不要更改 CI。
相关技能(已安装时使用)
java-junit(单元测试)、java-testcontainers(使用 Docker 的集成测试)、java-hibernate-jpa(持久化)、java-debugging(失败与堆栈跟踪)、java-diagnostics(性能、内存、线程、JFR)、java-upgrade(JDK/框架升级)、lsp-setup(用于导航与重构的 Java 语言服务器)。
参考文件
- references/modern-java.md:惯用法与已验证片段(record、sealed 类型、switch 模式、文本块、虚拟线程、SequencedCollection、未命名变量)、预览状态、陷阱。
- references/build-and-dependencies.md:Maven/Gradle 命令、wrapper、BOM、冲突诊断、更新检查、Dependabot/Renovate、漏洞扫描。
- references/quality-and-packaging.md:日志设置、-Xlint、Spotless、Error Prone、Checkstyle/SpotBugs 说明、jar/jlink/jpackage、GitHub Actions。