Coding

java-coding-guide-pro

Try it

Java 编码规范与避坑助手。在编写、修改、重构或审查任何 Java / Spring Boot 代码时使用本技能—— 无论用户是否提到编码规范或具体工具库(Java coding / code review / refactoring / best practices / code quality)。 覆盖:判空与字符串、集合与 Stream、日期时间、文件 IO / HTTP 调用 / JSON 序列化、 线程池与并发、Bean 拷贝、加密哈希、异常处理与日志、金额与浮点精确运算、 现代 Java 语法(JDK 8~25,按 LTS 版本门控)。 次级触发信号:new SimpleDate

What it does

Java 编码规范与避坑助手。在编写、修改、重构或审查任何 Java / Spring Boot 代码时使用本技能—— 无论用户是否提到编码规范或具体工具库(Java coding / code review / refactoring / best practices / code quality)。 覆盖:判空与字符串、集合与 Stream、日期时间、文件 IO / HTTP 调用 / JSON 序列化、 线程池与并发、Bean 拷贝、加密哈希、异常处理与日志、金额与浮点精确运算、 现代 Java 语法(JDK 8~25,按 LTS 版本门控)。 次级触发信号:new SimpleDateFormat、Executors.newXxx、new Thread()、double/float 算钱、 new BigDecimal(double)、BeanUtils.copyProperties、catch(Throwable)、手搓 MessageDigest、 log.error("x"+e) 拼接、Optional.get() 不判空、subList 分页、finally 中 return/throw、 Math.random() 强转生成序号/ID、Random 生成 token/验证码。 跟随项目既有技术栈(Spring / Hutool / commons-lang3 等),不强加任何库。 不适用:业务架构设计、框架选型、DDL、纯算法、前端代码。

The skill document

Java 编码指南

面向日常 Java 开发的编码约定助手。每条规则含「✗ 禁止 → ✓ 推荐 → 为什么」,覆盖 JDK 8~25+(LTS 锚定:8/11/17/21/25)。

三条铁律

  1. 栈中立:库的选择跟随项目既有依赖,本指南不强加任何库;Spring 项目优先 Spring 生态自带能力(Jackson / RestTemplate / WebClient / SLF4J)。
  2. 一域一默认:每个场景只给唯一推荐(以项目既有栈为准),不列举「或 A 或 B」制造决策疲劳。
  3. 版本门控:先确认目标 JDK,高版本特性按门控使用——JDK 8 项目严禁 var/record/switch 表达式/文本块/sealed/虚拟线程

第 0 步:栈探测与适配(激活时先执行)

pom.xml / build.gradle 一次性探测(读不到则一次问全,勿分多轮):

  1. 目标 JDKmaven.compiler.release / `` / sourceCompatibility;读不到问用户「目标 JDK 版本是(8 / 11 / 17 / 21 / 25)?」。
  2. 已有栈:Spring 系(自带 Jackson/RestTemplate/WebClient/SLF4J)、Hutool、commons-lang3、Guava、Gson/Fastjson、OkHttp、Lombok、MapStruct。
  3. 三条适配规则
    • 项目已有对应能力的库 → 跟随既有库,不另引、不混用(一个项目一套字符串/集合工具);仅当既有库缺该能力时补引,并在代码注释标注混用原因。
    • 高风险能力缺失且任务确实需要(见「高风险场景」表)→ 触发 C-CHECK 询问是否引入。
    • 低风险能力缺失(判空/集合/随机数/日期等)→ 直接用 JDK 原生,零打断、不询问

JDK 版本策略(五档 LTS 语义)

  • JDK 8(下限):可用 Optional/Stream/java.time/CompletableFuture/Lambda。 var/record/switch 表达式/文本块/sealed/虚拟线程/Stream.toList()
  • JDK 11:+ var(10)、JDK HttpClient(11)。
  • JDK 17:+ switch 表达式(14)、文本块(15)、record(16)、sealed(17)、Stream.toList()(16)、instanceof 模式匹配(16)。
  • JDK 21:+ 虚拟线程、switch 模式匹配、SequencedCollection、record 模式。
  • JDK 25:+ 22–24 转正特性(未命名变量 _、Stream Gatherers、Scoped Values 等);虚拟线程不再被 synchronized 钉住(JEP 491)。

LTS 锚定:门控只标 LTS;22–24 转正特性统一归入 25;preview/incubator 不纳入。详细门控见 references/09-modern-java.md

高风险场景优先成熟构件(本指南的核心立场)

以下场景手写极易出 bug,优先用成熟构件(顺序:项目既有库 > JDK 原生成熟 API > 推荐引入):

风险场景为什么手写危险项目无既有方案时的推荐
加密 / 哈希 / 密码hex 前导零丢失致碰撞;无盐哈希被彩虹表反查hutool-cryptoSecureUtil/BCrypt),触发 C-CHECK
线程池 / 并发Executors.newXxx 无界队列 OOM;中断状态丢失JDK ThreadPoolExecutor + CompletableFuture(原生即成熟)
JSON 解析手拼转义遗漏 / 注入Jackson ObjectMapper 复用单例(Spring 项目已自带)
Bean 映射Spring/Apache BeanUtils 源目标顺序相反,静默拷空MapStruct(编译期安全);无 processor 退 BeanUtil,触发 C-CHECK
HTTP 调用连接泄漏、超时缺省跟随 Spring(RestTemplate/WebClient);纯 Java 项目才 OkHttp3
金额运算二进制浮点无法精确表示十进制JDK BigDecimal(原生即成熟)

低风险场景(判空、集合新建/分块、随机数、日期格式化):项目有 Hutool / commons-lang3 就用其工具方法,没有就 JDK 原生(Objects/String.isBlank(11+)/List.of(9+)/ThreadLocalRandom/java.time),不触发任何询问

域 → 默认(项目无既有方案时;已有同类库按第 0 步跟随)

生成对应域代码前,先读「详见」列的 reference 文件:含该域完整的「✗ 禁止 → ✓ 推荐 → 为什么」规则、API 速查与 antipattern,本文规则表只是其摘要。

场景信号无既有方案时的默认详见
判 null / Optional 取值 / 相等防 NPEJDK Optional/Objects;有 Hutool 用 StrUtil/ObjectUtilreferences/01-null-and-string.md
字符串判空/格式化/截取/命名转换JDK 原生;有 Hutool 用 StrUtilreferences/01-null-and-string.md
集合判空/新建/分块/交并差JDK 原生;有 Hutool 用 CollUtilreferences/02-collection-stream.md
集合分组/转 MapJDK Stream/Collectorsreferences/02-collection-stream.md
日期格式化/解析/加减/当前时间JDK java.time.now() 显式传 ZoneId/Clock);遗留 Date 用 Hutool DateUtilreferences/03-date-time.md
文件读写/流拷贝JDK NIO + try-with-resources;有 Hutool 用 FileUtil/IoUtilreferences/04-io-http-json.md
HTTP 调用Spring 项目跟随 Spring;纯 Java 用 OkHttp3references/04-io-http-json.md
JSON 序列化Jackson ObjectMapper(复用单例)references/04-io-http-json.md
线程池/异步/虚拟线程JDK ThreadPoolExecutor + CompletableFuturereferences/05-concurrency.md
Bean 拷贝/转 MapMapStruct;无 processor 退 BeanUtilreferences/06-object-mapping.md
MD5/SHA/AES/密码哈希hutool-cryptoSecureUtil/BCryptreferences/07-crypto.md
异常链/断言/日志SLF4J 门面 + 占位符;有 Hutool 用 ExceptionUtil/Assertreferences/08-exception-logging.md
随机数/随机字符串/安全凭证ThreadLocalRandom;有 Hutool 用 RandomUtil;凭证类用 SecureRandomreferences/08-exception-logging.md
现代 Java 语法(版本门控)按目标 JDK 五档references/09-modern-java.md
金额/精确小数JDK BigDecimalreferences/10-bigdecimal.md
命名/OOP 规约/格式阿里 Java 开发手册规约references/11-conventions.md
方法嵌套过深/分支膨胀/认知复杂度卫语句 + 提炼语义方法 + 分支分发references/12-complexity.md

规则表(S/A 分级)

执行规则

  • S 级(bug/事故级):新代码禁止;审查/修改时发现既有代码命中 → 立即向用户提出改写。
  • A 级(风格约定):仅约束新生成代码;不主动改写用户既有代码、不发起任何询问;工具方法按第 0 步跟随既有栈。
级别✗ 模式✓ 改法为什么
SExecutors.newCachedThreadPool/newFixedThreadPoolnew Thread().start()new ThreadPoolExecutor + 有界队列 + 拒绝策略无界队列任务堆积 OOM
SSimpleDateFormat 作共享/静态字段;Calendar 手算java.time / DateUtil线程不安全;月从 0
Sdouble/float 算钱、new BigDecimal(double)bd.equals(...)、裸 divideBigDecimal(String) + compareTo + scale/RoundingMode浮点精度陷阱;equals 连 scale 一起比
S无盐 MD5/SHA 存密码BCrypt.hashpw彩虹表反查
S手搓 MessageDigest 且 hex 无 %02xSecureUtil.md5/sha256,或补 %02x前导零丢失致哈希碰撞
Scatch (InterruptedException e) {} 空吞Thread.currentThread().interrupt()中断丢失,线程池无法关停
Sfinally { throw/return }移除
Scatch (Throwable/Error)、空 catch 吞异常缩窄到具体类型分别处理
SOptional.get() 前无 isPresent/orXxxorElse/orElseThrow
SBeanUtils.copyProperties 未确认源/目标顺序MapStruct / BeanUtil(顺序固定 source,target)Spring 与 Apache 参数顺序相反,记错静默拷空
SsubList 结果当独立列表/分页ListUtil.partition 或拷贝 new ArrayList<>(view)
S手拼 JSON 字符串Jackson 等既有 JSON 库
SMath.random()/Random 生成"唯一"序号/单号/ID(如 (int)(Math.random()*100000) 当 seq)DB 序列 / Redis INCR / 雪花 ID 等单调发号器随机≠唯一:10 万空间约 400 次即 50% 碰撞(生日悖论),单号重复是事故
SRandom/ThreadLocalRandom/Math.random() 生成 token/验证码/密码/盐等安全凭证JDK SecureRandom(原生即成熟)线性同余可由少量输出反推种子,凭证可预测
S违反目标 JDK 版本门控(如 JDK 8 用 var/record按五档门控降级写法
A== null || .trim().isEmpty() 手写判空工具方法(StrUtil.isBlank / StringUtils / JDK isBlank(11+))
Aa.equals(b) 且 a 可能 nullObjects.equals / ObjectUtil.equal / 常量在前
A仅初始化就 new ArrayList<>() 逐个 add;subList 手写分块List.of / CollUtil.newArrayList/partition
Alog.error("x=" + e) 字符串拼接占位符 log.error("x={}", x, e),异常作最后参数拼接在日志关闭时也执行
ALocalDateTime.now()/LocalDate.now() 等 time-based now()now(zoneId) / now(clock)(应用级统一 ZoneId 常量或注入 Clock)隐式依赖 JVM 默认时区,容器多为 UTC,日切/对账跨天错 8 小时;Sonar java:S8688
Anew Random().nextInt() 手算范围、(int)(Math.random()*n) 强转RandomUtil.randomInt(min,max) / ThreadLocalRandom.current().nextInt(min,max)手算边界易错(半开区间);Math.random() 全局共享实例有锁竞争
A手拼随机字符串(Math.random()+String.format/自建字符表循环)RandomUtil.randomString(len) / randomNumbers(len)
APOJO 布尔属性 isXxx 前缀deleted 而非 isDeleted
A魔法值直出static final 常量或枚举
A无用 import(未使用/重复/java.lang/同包)残留移除;删掉某类最后一处使用时同步删 import虚假依赖信号、污染 diff;Sonar java:S1128
A单方法嵌套 ≥3 层、else-if ≥3 连、布尔混用 ≥3 项(预示认知复杂度超标)卫语句早返回 / 提炼语义方法 / switch、策略 Map 分发(禁无语义拆块)嵌套惩罚是计分大头,难读难测;Sonar java:S3776(阈值 15)
Aget/find 类方法返回 nullOptional 或空集合

C-CHECK 询问(仅高风险能力缺失时触发)

触发条件:任务确实需要加密/哈希/密码(项目无 crypto 能力)或 Bean 映射(无 MapStruct/Hutool),才向用户询问;低风险场景永不询问

  • 询问要点(一次问全,可与第 0 步的 JDK 提问合并):说明场景与推荐构件 → 给出坐标(下表)→ 两个选项:A) 引入并使用库;B) 不引入,手写实现。
  • 用户拒绝 → 受控降级:手写实现但按对应 reference(references/07-crypto.md / references/06-object-mapping.md)的 antipattern 保留守卫(如 hex 必须 %02x 补零;密码场景禁无盐并再次建议引入),并在代码注释标注这是受控降级。
依赖坐标说明
BOMcn.hutool:hutool-bom:5.8.47(dependencyManagement 中 import版本单一来源,模块不带 version;禁 hutool-all
corecn.hutool:hutool-coreStrUtil/CollUtil/DateUtil/BeanUtil/Base64 等
cryptocn.hutool:hutool-cryptoSecureUtil/DigestUtil/BCrypt/AES 全在 crypto(仅 Base64 在 core)

其他构件参考版本(JDK 8~25 兼容,仅在项目无同类库且确需时引入):MapStruct 1.5.5.Final(需 annotation processor)、Jackson 2.17.1、OkHttp3 4.12.0、Lombok 1.18.34、SLF4J 2.0.13(JDK 8 用 1.7.36)+ Logback。

Sonar S3252 与 Hutool 门面StrUtil.isBlank 等会命中):默认保留 StrUtil 等门面写法,不主动改写;仅当项目门禁启用该规则且阻断时,才全局换 CharSequenceUtil 或配置规则例外,禁混用、禁逐处 NOSONAR,详见 references/01-null-and-string.md

使用流程

  1. 第 0 步栈探测:目标 JDK + 已有栈,确定本次的工具选型基线。
  2. 定位并阅读 reference:查「域 → 默认」路由表,生成对应域代码前先读「详见」列文件(含该域完整规则与 antipattern,本文规则表仅是摘要)。
  3. 生成代码遵循规则表:S 级禁止项不出现;A 级约定用于新代码;审查/修改时 S 级命中既有代码 → 提出改写。
  4. 高风险能力缺失 → 触发 C-CHECK 询问,拒绝则受控降级。
  5. 输出前对 S 级规则逐项自检(尤其线程池、日期、金额、加密、随机数当序号、异常处理)。

版本与范围

  • Hutool 5.8.x(最新稳定 5.8.47,API 对照官方 javadoc 核实);JDK 8 为下限,门控见 references/09-modern-java.md
  • 去重原则:一个项目一套字符串/集合工具,不混用。已有 commons-lang3 → 用其 StringUtils/ObjectUtils,仅当缺该能力(如 BCrypt、DateUtil)才补对应 Hutool 模块并注释混用原因;已有 Hutool → 不再加 commons-lang3。

Related skills

Java 代码质量与安全的工具化门禁助手。在完成任何 Java / Spring Boot 代码的编写、修改、 重构后,或用户要求提交前检查、代码写完验证、代码审查 / code review、修复扫描告警、 质量门禁、静态扫描、安全扫描(SQL 注入 / 弱加密 / 路径穿越 / XXE / SSRF / 硬编码密钥)时使用本技能—— 无论用户是否提到具体工具(PMD / SpotBugs / FindSecBugs / Java 规约 / lint / static analysis)。 本技能用 JVM 插件链(PMD 7 + 自带规则集、SpotBugs + FindSecBugs)实

Java 单元测试**规范对齐**助手。在编写、评审、补全单元测试时使用本技能—— 无论用户是否提到具体框架(unit test / JUnit / Mockito / 测试用例 / 怎么测 / 测哪些 / 写多少测试)。 核心:统一团队的测试规范——用同一套设计方法(等价类/边界值/决策表/状态迁移)、 同一套默认(JUnit 5 原生断言、四维度必检)、同一套"写多少"的停止标准, 让不同人/不同对话产出的测试质量一致、可溯源、可审计,而非每次碰运气。 覆盖:一个方法必测的四维度(正向/反向/边界/异常)、最小充分集、 覆盖率反向校验、测试命名与组织、Mock 边界、"写多少"的成本收益判

1 installs

Java 开发规约速查手册,覆盖命名、异常、并发、数据库等 7 大维度核心规范。Use when 需要代码生成、编程辅助、调试测试、开发部署时使用。不适用于无明确技术栈的模糊需求。适用于独立开发者、企业团队和自动化工作流场景。支持中文交互,无需复杂配置即开即用。输出结果可直接使用,减少二次加工成本。

1 installs

项目代码规范守护者 — 分析/沉淀/执行项目规范,分模块按需加载,支持自进化。 支持前端(Vue/React/Next/Nuxt/Angular/Svelte)、Node.js、Python(Django/Flask/FastAPI)、 Java(Spring Boot/Spring Cloud)、Go(Gin/Echo/Fiber)、PHP(Laravel)、Rust 等多语言多框架。 自动检测项目语言生态,路由到对应分析指引文件。 触发词:分析项目规范|查看/检查规范|生成/修改/修复代码|写组件/页面/接口/API/服务/ SQL/数据库|重构/优化代码|Code Review|新建项目/初始化项目|规范review|代码review| 按项目规范|code style|code spec|项目用什么风格/技术栈/架构|项目规范是什么| 写一个XX|帮我写XX|新增XX功能|新建XX页面|这个XX怎么改|修复这个XX| 当 .code-spec/ 存在时自动生效,代码输出受规范约束。 Project code spec guardian — multi-language. Analyzes conventions, auto-loads specs. Triggers: analyze specs, show specs, write code per spec, fix bug, refactor, code review, write component/page/API/service/SQL. Multi-language support: Vue, React, Next, Nuxt, Angular, Svelte, Node.js, Python, Java, Go, PHP, Rust.

面向个人开发者的JavaScript代码风格指南,涵盖核心规则与基础代码审查能力。Use when 需要代码生成、编程辅助、调试测试、开发部署时使用。不适用于无明确技术栈的模糊需求。适用于独立开发者、企业团队和自动化工作流场景。支持中文交互,无需复杂配置即开即用。输出结果可直接使用,减少二次加工成本。

1 installs

Java 代码变更审查工具,按 6 大维度生成结构化审查报告与修复建议。Use when 需要代码生成、编程辅助、调试测试、开发部署时使用。不适用于无明确技术栈的模糊需求。适用于独立开发者、企业团队和自动化工作流场景。支持中文交互,无需复杂配置即开即用。输出结果可直接使用,减少二次加工成本。提供结构化输出和错误处理机制。

1 installs