Back to skills
SKILL.md
V3.5.0
ASecurityJava 编码规范与避坑助手。在编写、修改、重构或审查任何 Java / Spring Boot 代码时使用本技能—— 无论用户是否提到编码规范或具体工具库(Java coding / code review / refactoring / best practices / code quality)。 覆盖:判空与字符串、集合与 Stream、日期时间、文件 IO / HTTP 调用 / JSON 序列化、 线程池与并发、Bean 拷贝、加密哈希、异常处理与日志、金额与浮点精确运算、 现代 Java 语法(JDK 8~25,按特性最低版本门控)。 次级触发信号——代码中出现:SimpleDateFormat、Executors.newFixedThreadPool / newCachedThreadPool / newSingleThreadExecutor、new Thread(...)、 new BigDecimal(0.1) 小数构造、BeanUtils.copyProperties、catch (Throwable) / catch (InterruptedExcept...
- 2 stars
- 0 votes
- 0 copies
- 0 views
- Added October 22, 2026
Works with
Security analysis
100/100Pro scans all 13 files and shows the line behind each finding
npx -y skills add BaixuanZhu/skills --skill v3.5.0 --agent claude-codeAre you the author of V3.5.0?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/baixuanzhu-v3-5-0)---
name: java-coding-guide-pro
slug: java-coding-guide-pro
displayName: Java 编码指南
description: >-
Java 编码规范与避坑助手。在编写、修改、重构或审查任何 Java / Spring Boot 代码时使用本技能——
无论用户是否提到编码规范或具体工具库(Java coding / code review / refactoring /
best practices / code quality)。
覆盖:判空与字符串、集合与 Stream、日期时间、文件 IO / HTTP 调用 / JSON 序列化、
线程池与并发、Bean 拷贝、加密哈希、异常处理与日志、金额与浮点精确运算、
现代 Java 语法(JDK 8~25,按特性最低版本门控)。
次级触发信号——代码中出现:SimpleDateFormat、Executors.newFixedThreadPool /
newCachedThreadPool / newSingleThreadExecutor、new Thread(...)、
new BigDecimal(0.1) 小数构造、BeanUtils.copyProperties、catch (Throwable) /
catch (InterruptedException) 空块、MessageDigest(手写 MD5/SHA)、
log.error("x=" + x) 日志拼接、Optional.get()、subList(...)、
finally 块内 return / throw、Math.random()、new Random();
用户任务词出现:生成订单号 / 流水号 / 唯一 ID、生成验证码 / token / 盐、
密码加密 / 哈希存储、金额 / 价格计算、线程池 / 异步任务、日期格式化 / 时区。
跟随项目既有技术栈(Spring / Hutool / commons-lang3 等),不强加任何库。
不适用:业务架构设计、框架选型、DDL、纯算法、前端代码。
version: "3.5.0"
last_verified: "2026-08-23"
---
# 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. **目标 JDK**:`maven.compiler.release` / `<source>` / `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 版本策略
**判据:目标 JDK ≥ 特性最低版本 → 可用;低于 → 禁用,改低版本写法。** 非 LTS 目标同样按版本比较,不另设档位。
| 特性 | 最低 JDK |
|---|---|
| Lambda / 方法引用 / `Optional` / `Stream` / `java.time` / `CompletableFuture` | 8(下限) |
| `var`(仅局部变量) | 10 |
| JDK 内置 `HttpClient` | 11 |
| `switch` 表达式(箭头 / `yield`) | 14 |
| 文本块 `"""` | 15 |
| `record` / `Stream.toList()`(不可变)/ `instanceof` 模式匹配 | 16 |
| `sealed` | 17 |
| 虚拟线程 / `switch` 模式匹配 / `SequencedCollection` | 21 |
| 未命名变量 `_` / Stream Gatherers / Scoped Values(22–24 转正,完整清单见 09) | 25 |
> 22–24 转正特性统一按 25 门控;preview/incubator 不纳入。虚拟线程 + `synchronized` 在 21 会钉住载体线程(改 `ReentrantLock`),25 解除(JEP 491)。完整门控表(含推荐度)见 `references/09-modern-java.md`。
## 风险分级与构件选择
**构件选择顺序**:项目既有库 > JDK 原生 API > 引入新库(引入前触发 C-CHECK)。
- **高风险场景**(手写极易出 bug,**禁手写,必须用成熟构件**;具体推荐见「域 → 默认」表):加密 / 哈希 / 密码、线程池 / 并发、JSON 解析、Bean 映射、HTTP 调用、金额运算。其中项目缺**加密**或 **Bean 映射**能力时触发 C-CHECK 询问;其余场景 JDK 原生 / Spring 自带即可覆盖,不询问。
- **低风险场景**(零打断):判空、集合新建 / 分块、随机数、日期格式化——项目有 Hutool / commons-lang3 就用其工具方法,没有就 JDK 原生(`Objects`/`String.isBlank`(11+)/`List.of`(9+)/`ThreadLocalRandom`/`java.time`),不触发任何询问。
## 域 → 默认(项目无既有方案时;已有同类库按第 0 步跟随)
> 生成对应域代码前,**先读「详见」列的 reference 文件**:含该域完整的「✗ 禁止 → ✓ 推荐 → 为什么」规则、API 速查与 antipattern,本文规则表只是其摘要。
| 场景信号 | 无既有方案时的默认 | 详见 |
|---|---|---|
| 判 null / `Optional` 取值 / 相等防 NPE | JDK `Optional`/`Objects`;有 Hutool 用 `StrUtil`/`ObjectUtil` | `references/01-null-and-string.md` |
| 字符串判空/格式化/截取/命名转换 | JDK 原生;有 Hutool 用 `StrUtil` | `references/01-null-and-string.md` |
| 集合判空/新建/分块/交并差 | JDK 原生;有 Hutool 用 `CollUtil` | `references/02-collection-stream.md` |
| 集合分组/转 Map | JDK `Stream`/`Collectors` | `references/02-collection-stream.md` |
| 日期格式化/解析/加减/当前时间 | JDK `java.time`(`.now()` 显式传 ZoneId/Clock);遗留 `Date` 用 Hutool `DateUtil` | `references/03-date-time.md` |
| 文件读写/流拷贝 | JDK NIO + try-with-resources;有 Hutool 用 `FileUtil`/`IoUtil` | `references/04-io-http-json.md` |
| HTTP 调用 | Spring 项目跟随 Spring;纯 Java 用 OkHttp3 | `references/04-io-http-json.md` |
| JSON 序列化 | Jackson `ObjectMapper`(复用单例) | `references/04-io-http-json.md` |
| 线程池/异步/虚拟线程 | JDK `ThreadPoolExecutor` + `CompletableFuture` | `references/05-concurrency.md` |
| Bean 拷贝/转 Map | MapStruct;无 processor 退 `BeanUtil` | `references/06-object-mapping.md` |
| MD5/SHA/AES/密码哈希 | `hutool-crypto`(`SecureUtil`/`BCrypt`) | `references/07-crypto.md` |
| 异常链/断言/日志 | SLF4J 门面 + 占位符;有 Hutool 用 `ExceptionUtil`/`Assert` | `references/08-exception-logging.md` |
| 随机数/随机字符串/安全凭证 | `ThreadLocalRandom`;有 Hutool 用 `RandomUtil`;凭证类用 `SecureRandom` | `references/08-exception-logging.md` |
| 现代 Java 语法(版本门控) | 按「JDK 版本策略」特性最低版本 | `references/09-modern-java.md` |
| 金额/精确小数 | JDK `BigDecimal` | `references/10-bigdecimal.md` |
| 命名/OOP 规约/格式 | 规约条目(无库选型) | `references/11-conventions.md` |
| 方法嵌套过深/分支膨胀/认知复杂度 | 卫语句 + 提炼语义方法 + 分支分发 | `references/12-complexity.md` |
## 规则表(S/A 分级)
**执行规则**:
- **S 级(bug/事故级)**:新代码禁止;审查/修改时发现**既有代码**命中 → 立即向用户提出改写。
- **A 级(风格约定)**:仅约束**新生成代码**;不主动改写用户既有代码、不发起任何询问;工具方法按第 0 步跟随既有栈。
| 级别 | ✗ 模式 | ✓ 改法 |
|---|---|---|
| S | `Executors.newCachedThreadPool`/`newFixedThreadPool`、`new Thread().start()` | `new ThreadPoolExecutor` + 有界队列 + 拒绝策略 |
| S | `SimpleDateFormat` 作共享/静态字段;`Calendar` 手算(月份从 0 起) | `java.time` / `DateUtil` |
| S | `double`/`float` 算钱、`new BigDecimal(double)`、`bd.equals(...)`、裸 `divide` | `BigDecimal(String)` + `compareTo` + scale/`RoundingMode` |
| S | 无盐 MD5/SHA 存密码 | `BCrypt.hashpw` |
| S | 手搓 `MessageDigest` 且 hex 无 `%02x` | `SecureUtil.md5`/`sha256`,或补 `%02x` |
| S | `catch (InterruptedException e) {}` 空吞 | 加 `Thread.currentThread().interrupt()` |
| S | `finally { throw/return }` | 移除 |
| S | `catch (Throwable/Error)`、空 catch 吞异常 | 缩窄到具体类型分别处理 |
| S | `Optional.get()` 前无 `isPresent`/`orXxx` | `orElse`/`orElseThrow` |
| S | `BeanUtils.copyProperties` 未确认源/目标顺序(Spring 与 Apache 参数顺序相反) | MapStruct / `BeanUtil`(顺序固定 source,target) |
| S | `subList` 结果当独立列表/分页 | `ListUtil.partition` 或拷贝 `new ArrayList<>(view)` |
| S | 手拼 JSON 字符串 | Jackson 等既有 JSON 库 |
| S | `Math.random()`/`Random` 生成"唯一"序号/单号/ID(如 `(int)(Math.random()*100000)` 当 seq) | DB 序列 / Redis `INCR` / 雪花 ID 等单调发号器 |
| S | `Random`/`ThreadLocalRandom`/`Math.random()` 生成 token/验证码/密码/盐等安全凭证 | JDK `SecureRandom`(原生即成熟) |
| S | 违反目标 JDK 版本门控(如 JDK 8 用 `var`/`record`) | 按版本门控降级写法 |
| A | `== null \|\| .trim().isEmpty()` 手写判空 | 工具方法(`StrUtil.isBlank` / `StringUtils` / JDK `isBlank`(11+)) |
| A | `a.equals(b)` 且 a 可能 null | `Objects.equals` / `ObjectUtil.equal` / 常量在前 |
| A | 仅初始化就 `new ArrayList<>()` 逐个 add;`subList` 手写分块 | `List.of` / `CollUtil.newArrayList`/`partition` |
| A | `log.error("x=" + e)` 字符串拼接 | 占位符 `log.error("x={}", x, e)`,异常作最后参数 |
| A | 裸 `LocalDateTime.now()`/`LocalDate.now()` 等 time-based `now()`(隐式 JVM 默认时区;Sonar java:S8688) | `now(zoneId)` / `now(clock)`(应用级统一 ZoneId 常量或注入 Clock) |
| A | `new Random().nextInt()` 手算范围、`(int)(Math.random()*n)` 强转 | `RandomUtil.randomInt(min, max)`([min, max) 半开)/ `ThreadLocalRandom.current().nextInt(min, max)` |
| A | 手拼随机字符串(`Math.random()`+`String.format`/自建字符表循环) | `RandomUtil.randomString(len)` / `randomNumbers(len)` |
| A | POJO 布尔属性 `isXxx` 前缀 | 用 `deleted` 而非 `isDeleted` |
| A | 魔法值直出 | 抽 `static final` 常量或枚举 |
| A | 无用 import(未使用/重复/java.lang/同包;Sonar java:S1128)残留 | 移除;删掉某类最后一处使用时同步删 import |
| A | 单方法嵌套 ≥3 层、else-if ≥3 连、布尔混用 ≥3 项(Sonar java:S3776 认知复杂度阈值 15) | 卫语句早返回 / 提炼语义方法 / switch、策略 Map 分发(禁无语义拆块) |
| A | `get`/`find` 类方法返回 null | `Optional<T>` 或空集合 |
## C-CHECK 询问(仅高风险能力缺失时触发)
**触发条件**:任务确实需要**加密/哈希/密码**(项目无 crypto 能力)或 **Bean 映射**(无 MapStruct/Hutool),才向用户询问;低风险场景**永不询问**。
- **询问要点**(一次问全,可与第 0 步的 JDK 提问合并):说明场景与推荐构件 → 给出坐标(下表)→ 两个选项:A) 引入并使用库;B) 不引入,手写实现。
- **用户拒绝 → 受控降级**:手写实现但按对应 reference(`references/07-crypto.md` / `references/06-object-mapping.md`)的 antipattern 保留守卫(如 hex 必须 `%02x` 补零;密码场景禁无盐并再次建议引入),并在代码注释标注这是受控降级。
| 依赖 | 坐标 | 说明 |
|---|---|---|
| BOM | `cn.hutool:hutool-bom:5.8.47`(dependencyManagement 中 `import`) | 版本单一来源,模块不带 version;禁 `hutool-all` |
| core | `cn.hutool:hutool-core` | StrUtil/CollUtil/DateUtil/BeanUtil/Base64 等 |
| crypto | `cn.hutool:hutool-crypto` | `SecureUtil`/`DigestUtil`/`BCrypt`/`AES` **全在 crypto**(仅 `Base64` 在 core) |
其他构件参考版本(项目无同类库且确需时才引入):
| 构件 | 参考版本 | 门控 / 备注 |
|---|---|---|
| MapStruct | 1.5.5.Final | 需 annotation processor(编译期生成) |
| Jackson | 2.17.1 | Spring 项目跟随 Boot 自带版本 |
| OkHttp3 | 4.12.0 | 纯 Java 项目 HTTP |
| Lombok | 1.18.34 | JDK 8+ |
| SLF4J + Logback | 2.0.13 + 1.5.x | 需 JDK 11+;JDK 8 用 SLF4J 1.7.36 + Logback 1.2.x,两套禁混用(见 `references/08-exception-logging.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。
Files in this skill
- SKILL.md
- references/01-null-and-string.md
- references/02-collection-stream.md
- references/03-date-time.md
- references/04-io-http-json.md
- references/05-concurrency.md
- references/06-object-mapping.md
- references/07-crypto.md
- references/08-exception-logging.md
- references/09-modern-java.md
- references/10-bigdecimal.md
- references/11-conventions.md
- references/12-complexity.md
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.