full-stack-skills/java-skills

commons-patterns

Apache Commons 最佳实践模式。从官方文档提炼,覆盖 Commons Lang3(StringUtils千面判空/isEmpty vs isBlank/Validate抛NullPointerException迁移)、Commons IO(IOUtils.toString大文件陷阱/FileUtils.lineIterator逐行读模式/FilenameUtils.normalize路径规范化)、Commons Collections4(CollectionUtils.union/intersection/subtract集合运算)。 纠正 LLM 误用:混淆 StringUtils.isBlank vs isEmpty、IOUtils.toString 读大文件OOM、不知道 LineIterator 逐行读模式、用 lang 而非 lang3 ?

First seen Jun 18, 2026

Installation

$ npx skills add full-stack-skills/java-skills --skill commons-patterns

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 full-stack-skills/java-skills · top by installs.

npx skills add full-stack-skills/java-skills

Browse all from full-stack-skills/java-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 5
License LICENSE
Default branch main
Status Active

Skill metadata

Parsed from SKILL.md frontmatter.

LicenseApache-2.0

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 6,756 B
  • docs SUMMARY.md 560 B

History

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

SKILL.md

Apache Commons 最佳实践模式

来源: Commons Home | Lang3 User Guide | IO Description

Capability Boundaries

✅ Strong Suits

  1. StringUtils 判空模式 — isEmpty vs isBlank vs defaultString 精确语义选择
  2. Commons IO 文件操作 — FileUtils 读写复制 / IOUtils 流操作 / LineIterator 逐行
  3. Commons Collections4 — CollectionUtils/MultiValuedMap/MapUtils
  4. RandomStringUtils — 生成随机字符串(验证码/Token/临时密码)
  5. Validate — 参数校验(注意3.0起抛NullPointerException而非IllegalArgumentException)

❌ Out of Scope

  1. 中文特色(身份证/拼音) → hutool-patterns
  2. 不可变集合/缓存/EventBus → guava-patterns
  3. Bean映射/JSON → mapstruct-patterns/jackson-patterns

Commons vs Guava vs Hutool 选择表

场景 Commons Guava Hutool 优先选
字符串判空/截断/填充 ⭐⭐⭐ ⭐⭐ ⭐⭐⭐ 任意(团队约定)
文件复制/删除/读行 ⭐⭐⭐ ⭐ ⭐⭐ Commons IO
文件名/路径处理 ⭐⭐⭐ — ⭐⭐ Commons IO
集合运算(交/并/差) ⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐ 任意
日期处理(旧Date) ⭐ — ⭐⭐⭐ Java8 Time
随机字符串 ⭐⭐⭐ — ⭐⭐ Commons Lang3
HTML/XML转义 ⭐⭐⭐ — ⭐ Commons Lang3
数学/统计 ⭐⭐⭐ — ⭐ Commons Math

核心模式

模式 1: StringUtils 判空精确语义

// ✅ isEmpty: null 或 "" → true (不含空格)
StringUtils.isEmpty(null);    // true
StringUtils.isEmpty("");      // true
StringUtils.isEmpty(" ");     // false ← 注意!
StringUtils.isEmpty("abc");   // false

// ✅ isBlank: null 或 空白字符 → true
StringUtils.isBlank(null);    // true
StringUtils.isBlank("");      // true
StringUtils.isBlank(" ");     // true ← 含空格也true
StringUtils.isBlank("abc");   // false

// ✅ 选择规则: 表单验证用isBlank(不接受空白输入),集合判空用isEmpty

// ✅ defaultString: null安全取值
StringUtils.defaultString(str, "");         // null → ""
StringUtils.defaultIfBlank(str, "N/A");     // null/""/" " → "N/A"

// ✅ 填充与截断
StringUtils.leftPad("1", 3, '0');           // "001"
StringUtils.abbreviate("very long text", 10); // "very lo..."

模式 2: Commons IO 文件模式

// ✅ 读取整个文件(小文件,<10MB)
String content = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
List<String> lines = FileUtils.readLines(file, StandardCharsets.UTF_8);

// ✅ 逐行读(大文件) — LineIterator 模式
LineIterator it = FileUtils.lineIterator(file, "UTF-8");
try { while (it.hasNext()) { String line = it.nextLine(); /* 处理 */ }
} finally { LineIterator.closeQuietly(it); }

// ✅ 流操作(需手动关流)
InputStream in = new URL("https://example.com").openStream();
try { String result = IOUtils.toString(in, StandardCharsets.UTF_8); }
finally { IOUtils.closeQuietly(in); }

// ❌ 反模式: IOUtils.toString() 读 1GB 文件 → 尝试创建1GB String → OOM

// ✅ 写入/复制/删除
FileUtils.writeStringToFile(file, content, StandardCharsets.UTF_8);
FileUtils.copyFile(src, dest);
FileUtils.forceMkdir(dir);          // 递归创建目录
FileUtils.deleteDirectory(dir);      // 递归删除

// ✅ 文件名处理
FilenameUtils.getExtension("archive.tar.gz");  // "gz" (最后一个.)
FilenameUtils.getBaseName("/path/file.txt");   // "file"
String normalized = FilenameUtils.normalize("C:/a/../b/file.txt"); // "C:/b/file.txt"

模式 3: Commons Lang3 迁移注意事项

// ❌ 旧包名 — 不要用
import org.apache.commons.lang.StringUtils;

// ✅ 新包名(3.0+) — 必须用
import org.apache.commons.lang3.StringUtils;

// Maven坐标
// groupId: commons-lang → org.apache.commons
// artifactId: commons-lang → commons-lang3

模式 4: Validate 的参数校验

// ⚠️ Commons Lang 3.0 变化: Validate 校验 null 抛 NullPointerException
// (对齐JDK标准行为,以前抛 IllegalArgumentException)
Validate.notNull(obj, "参数不能为空: %s", name);   // 抛 NPE
Validate.isTrue(age > 0, "年龄必须>0");             // 抛 IllegalArgumentException
// 注意:验证null用Validate.notNull,验证状态用Validate.isTrue

模式 5: RandomStringUtils

// ✅ 随机字母数字(验证码/Token)
RandomStringUtils.randomAlphanumeric(6);      // "a3Bx9K"
RandomStringUtils.randomAlphanumeric(32);     // 32位Token
// ✅ 随机数字
RandomStringUtils.randomNumeric(6);           // "482931"
// ✅ 随机字母
RandomStringUtils.randomAlphabetic(8);        // "AbCdEfGh"

模式 6: 集合运算

// ⚠️ 包名: org.apache.commons.collections4 (不是 collections)
CollectionUtils.isEmpty(coll);
CollectionUtils.union(list1, list2);          // 并集
CollectionUtils.intersection(list1, list2);   // 交集
CollectionUtils.subtract(list1, list2);       // 差集(list1 - list2)

MapUtils.getString(map, "key", "default");    // null安全取值

Gotchas

  1. isEmpty vs isBlank — isEmpty(" ")→true(不含空格),isBlank(" ")→true(含空格)
  2. IOUtils.toString 加载整个流到内存 — 大文件(>10MB)用 LineIterator 逐行读
  3. IOUtils.toString 不关流 — 配合 finally { IOUtils.closeQuietly(in) }
  4. Lang3 DateUtils 与 Java8 LocalDateTime 不兼容 — 用 java.time API,仅旧Date用Commons
  5. Collections4 包名是 collections4 — 不是 collections(那是3.x)
  6. Lang3 3.0 起 isAlpha/isNumeric/isAlphanumeric("")→false — 以前版本返回true
  7. Maven坐标: groupId=org.apache.commons, artifactId=commons-lang3 — 不是 commons-lang
  8. Validate.notNull 抛 NullPointerException — Validate.isTrue 抛 IllegalArgumentException

Data Privacy

本技能不收集、存储或传输任何用户数据。