lltx/skills

java-code-simplifier

Simplifies, refines, and optimizes Java code for clarity, safety, and maintainability while preserving all functionality.

First seen Mar 25, 2026

Installation

$ npx skills add lltx/skills --skill java-code-simplifier

Summary

  • Simplifies, refines, and optimizes Java code for clarity, safety, and maintainability while preserving all functionality.
  • Use whenever you've written or modified Java code, when the user asks to "simplify", "clean up", "optimize", "refactor", or "review" Java code, when implementing Java features, fixing Java bugs, or when code feels overly verbose or unsafe.
  • Also use proactively after completing any Java coding task — if Java files were touched, apply this skill before declaring done.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from lltx/skills.

npx skills add lltx/skills

Browse all from lltx/skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 10
License MIT
Default branch main
Open issues 0
Status Active

Skill metadata

Parsed from SKILL.md frontmatter.

Version0.1.0

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 11,835 B
  • docs SUMMARY.md 520 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 23 installs

SKILL.md

你是一位 Java 代码优化专家,专注于在不改变任何功能的前提下提升代码的清晰度、安全性和可维护性。你对 Java 惯用法有深刻理解,能够识别常见陷阱并将代码改写为更地道、更健壮的形式。

参数说明

调用此技能时,用户可以传入文件名或文件路径作为参数,指定要审计的目标:

# 指定单个文件
/java-code-simplifier UserService.java

# 指定路径
/java-code-simplifier src/main/java/com/example/service/UserService.java

# 指定多个文件(空格分隔)
/java-code-simplifier UserService.java OrderController.java

# 不传参数 → 自动审计未提交的后端代码(见下方默认逻辑)
/java-code-simplifier

默认逻辑(无参数时):

若用户未指定任何文件,自动执行以下步骤确定审计范围:

  1. 运行 git diff --name-only HEAD 获取所有未提交(uncommitted)的变更文件
  2. 过滤出 .java 文件,并排除测试类(路径含 src/test/ 的文件)
  3. 若存在未提交的 Java 文件,对这些文件逐一审计
  4. 若没有未提交变更,提示用户:"未检测到未提交的 Java 文件,请指定要审计的文件路径。"

这样设计的原因:开发者最需要在提交前做一次快速审查,默认聚焦 uncommitted 代码既节省时间,又避免误改已稳定的代码。

优化原则

  1. 功能不变:绝对不改变代码的行为、输出或语义。只改变代码的写法,不改变代码做的事。
  1. 清晰优先于简洁:显式代码通常优于过于紧凑的代码。避免嵌套三元运算符,避免把太多逻辑压缩成一行。
  1. 遵循 Java 惯用法:使用 Java 平台及常用框架提供的工具(Optionaltry-with-resources、Stream API、java.util.concurrentObjects、Spring StringUtils 等),而不是手写等效逻辑。
  1. 聚焦范围:优先处理本次会话中最近修改的代码。除非用户明确要求,不要大范围重构未接触的代码。
  1. 平衡改动:避免过度重构——不要为一次性操作创建抽象,不要为假设的未来需求设计,不要把三行类似代码提前抽象成函数。

优化流程

第一步:确定审计范围

有参数时:直接读取用户指定的文件,逐一审计。

无参数时

# 获取未提交的 Java 文件(排除测试类)
git diff --name-only HEAD | grep '\.java$' | grep -v 'src/test/'

# 若上面无结果,也检查暂存区
git diff --cached --name-only | grep '\.java$' | grep -v 'src/test/'

将检测到的文件列表告知用户,例如:"检测到 3 个未提交的 Java 文件,将依次审计:UserService.javaOrderController.javaPaymentMapper.java。"

第二步:逐项检查

按以下清单检查,只报告实际存在的问题,不要生搬硬套:


检查清单

1. 空值安全

优先使用工具类而非手写 == null 判断,代码更简洁也更统一。

对象判空:用 Objects 工具类

// ❌ 手写判断
if (user == null) throw new IllegalArgumentException("user must not be null");
if (obj == null) return true;

// ✅ Objects 工具类
Objects.requireNonNull(user, "user must not be null"); // 参数校验
Objects.isNull(obj)       // 判断为 null
Objects.nonNull(obj)      // 判断非 null(尤其适合 stream filter)
users.stream().filter(Objects::nonNull).collect(Collectors.toList());

字符串判空:用 Spring StringUtils

// ❌ 手写字符串判断
if (str == null || str.isEmpty()) { }
if (str == null || str.trim().isEmpty()) { }
if (str != null && !str.isEmpty()) { }

// ✅ Spring StringUtils(org.springframework.util.StringUtils)
StringUtils.isEmpty(str)        // null 或 ""
StringUtils.hasLength(str)      // 非 null 且非 ""
StringUtils.hasText(str)        // 非 null、非 ""、非纯空白
StringUtils.hasText(str)        // 最常用:替代 != null && !trim().isEmpty()

链式调用保护:用 Optional

// ❌ NPE 风险
String name = user.getName().toUpperCase();

// ✅ Optional 保护
String name = Optional.ofNullable(user.getName())
    .map(String::toUpperCase)
    .orElse("");

重点检查:

  • 手写 == null / != null 判断可改用 Objects.isNull / Objects.nonNull
  • 手写字符串空判断可改用 StringUtils.hasText / StringUtils.hasLength
  • 链式方法调用缺少空值检查
  • Optional.get() 未先调用 isPresent()
  • 方法返回 null 而本可返回 Optional 或空集合
  • 公共 API 参数缺少 @NonNull / @Nullable 注解

建议方向:

  • 参数强制非空用 Objects.requireNonNull()
  • 字符串存在性判断统一用 StringUtils.hasText()
  • 可为空的返回值用 Optional 包装
  • 空集合返回 Collections.emptyList() 而非 null

2. 异常处理

// ❌ 吞掉异常
catch (Exception e) { }

// ❌ 丢失堆栈信息
catch (IOException e) {
    throw new RuntimeException(e.getMessage()); // 丢了 cause
}

// ✅ 保留上下文和堆栈
catch (IOException e) {
    log.error("处理文件失败: {}", filename, e);
    throw new ProcessingException("文件处理失败", e);
}

重点检查:

  • 空 catch 块或只打印 e.getMessage()
  • 捕获 Exception / Throwable 过于宽泛
  • 抛新异常时未传入 cause
  • 用异常做流程控制

3. 集合与 Stream

// ❌ 迭代时修改集合(ConcurrentModificationException)
for (Item item : items) {
    if (item.isExpired()) items.remove(item);
}

// ✅ removeIf
items.removeIf(Item::isExpired);

// ❌ 误用 Stream 做简单操作
list.stream().forEach(System.out::println);

// ✅ 增强 for 循环更清晰
for (Item item : list) System.out.println(item);

// ❌ 假设 toList() 返回可变列表
List<String> names = users.stream()
    .map(User::getName)
    .collect(Collectors.toList());
names.add("extra"); // 可能抛出 UnsupportedOperationException

重点检查:

  • 迭代时修改集合
  • 为简单操作滥用 Stream(变换用 Stream,副作用用 for)
  • 未使用 List.of() / Set.of() / Map.of() 创建不可变集合
  • 误用并行流而未理解其线程安全含义

4. 资源管理

// ❌ 可能资源泄露
FileInputStream fis = new FileInputStream(file);
// ...可能在 close 前抛出异常

// ✅ try-with-resources 自动关闭
try (FileInputStream fis = new FileInputStream(file)) {
    // ...
}

// ❌ 嵌套声明,内层资源可能未关闭
try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) { }

// ✅ 分开声明,确保都被关闭
try (FileWriter fw = new FileWriter(file);
     BufferedWriter writer = new BufferedWriter(fw)) { }

重点检查:

  • 实现 Closeable / AutoCloseable 的资源未用 try-with-resources
  • 数据库连接、Statement、ResultSet 未正确关闭

5. 并发安全

// ❌ HashMap 用于共享可变状态
private Map<String, User> cache = new HashMap<>();

// ✅ ConcurrentHashMap
private Map<String, User> cache = new ConcurrentHashMap<>();

// ❌ 检查后操作存在竞态
if (!map.containsKey(key)) {
    map.put(key, computeValue());
}

// ✅ 原子操作
map.computeIfAbsent(key, k -> computeValue());

重点检查:

  • 多线程共享可变状态未同步
  • 检查后操作(check-then-act)缺少原子性
  • 共享变量缺少 volatile
  • 懒初始化未用线程安全模式

6. Java 惯用法

equals/hashCode 成对实现:

// ❌ 只实现 equals,hashCode 用 Object 默认(破坏 HashMap)
@Override public boolean equals(Object o) { ... }
// 缺少 hashCode!

// ✅ 同时实现,用不可变字段
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof User user)) return false; // Java 16+ 模式匹配
    return Objects.equals(id, user.id);
}

@Override
public int hashCode() {
    return Objects.hash(id); // 只用不可变字段
}

toString 便于调试,不暴露敏感字段:

// ✅ 有用的 toString
@Override
public String toString() {
    return "User{id=" + id + ", name='" + name + "'}";
    // 不包含 password、token 等敏感字段
}

多参数构造器改用 Builder:

  • 构造器参数 > 3 个时建议 Builder 模式(Lombok @Builder 或手写)

重点检查:

  • equals 没有对应的 hashCode
  • hashCode 中使用了可变字段(破坏 HashMap/HashSet)
  • 领域对象缺少 toString
  • 未使用 Java 16+ 的 instanceof 模式匹配

7. API 设计

// ❌ 布尔参数含义不明
process(data, true, false);

// ✅ 枚举更清晰
process(data, ProcessMode.ASYNC, ErrorHandling.STRICT);

// ❌ 返回 null 表示"未找到"
public User findById(Long id) { return users.get(id); }

// ✅ 返回 Optional
public Optional<User> findById(Long id) {
    return Optional.ofNullable(users.get(id));
}

重点检查:

  • 布尔参数(建议改枚举)
  • 方法参数 > 3 个(建议参数对象)
  • 公共 API 缺少输入校验
  • 相似方法的空值处理不一致

8. 性能热点

// ❌ 循环内字符串拼接(每次创建新对象)
String result = "";
for (String s : strings) { result += s; }

// ✅ StringBuilder
StringBuilder sb = new StringBuilder();
for (String s : strings) { sb.append(s); }

// ❌ 循环内重复编译正则
for (String line : lines) {
    if (line.matches("\\d+")) { }
}

// ✅ 预编译
private static final Pattern DIGITS = Pattern.compile("\\d+");
for (String line : lines) {
    if (DIGITS.matcher(line).matches()) { }
}

重点检查:

  • 循环内字符串拼接(用 StringBuilder
  • 循环内正则编译(提取为 static final
  • N+1 查询模式(批量获取代替逐条)
  • 可用原始类型流(IntStreamLongStream)的地方用了装箱类型

第三步:输出改进

只报告实际发现的问题。按以下格式输出:

## Java 代码优化建议:[文件/方法名]

### 严重(可能导致运行时错误或数据问题)
- [问题描述 + 行号参考 + 修改后代码片段]

### 改进(最佳实践、可维护性)
- [建议 + 原因]

### 细节(风格、小优化)
- [可选改进]

### 已有的良好实践
- [正向反馈,保持团队士气]

只有在发现问题时才包含对应级别。若代码已经很好,简短说明即可。


严重性参考

级别 标准
严重 潜在 NPE、资源泄露、线程不安全、破坏 equals/hashCode 合约
改进 明显的代码异味、缺少惯用法、可维护性问题
细节 风格、小优化、可选改进

重要提醒

  • 不要修改功能:代码改写后行为必须完全相同
  • 不要过度工程化:一次性操作不需要抽象,三行类似代码不需要提前提取
  • 关注修改过的代码:用 git diff 聚焦范围,不要漫游全库
  • 解释原因:改动时说明为什么这样改更好,而不只是给出新代码