Apache Commons Lang 3.21.0 快速入门与集成示例
Apache Commons Lang 3.21.0 十分钟快速入门,Maven 引入后用一个程序实测 StringUtils、Pair、Range,附 javac/java -cp 直跑、中文编码配置、与 Guava 同 classpath 共存实测与常见错误解决。
Apache Commons Lang 3.21.0 快速入门与集成示例
目标:用 10 分钟把 Apache Commons Lang 3.21.0 跑起来——Maven 引入依赖、写出第一个使用 StringUtils/Pair/Range 的完整程序并看到真实输出,随后完成 javac/java -cp 直跑验证、中文编码配置,并实测与 Guava 同 classpath 共存。以下全部命令与输出均已在 Ubuntu 22.04(x86_64)实测通过。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- JDK:OpenJDK 17.0.20.1
- 构建工具:Apache Maven 3.6.3
- 目标库:org.apache.commons:commons-lang3:3.21.0(2026-09-29 发布,零传递依赖,最低 Java 8)
- 共存验证库:com.google.guava:guava:32.1.3-jre(仅第七章使用)
- 示例工程目录:/opt/lang-demo(从零搭建的完整过程见《Ubuntu 22.04 安装 Apache Commons Lang 指南》)
说明:本文所有运行命令统一带
-Dfile.encoding=UTF-8,原因与实测对比见第六章。
二、前置条件
- JDK 与 Maven 就绪:
java -version与mvn -v有正常回显即可。本实测环境:
java -version 2>&1 | head -1
mvn -v | head -1
输出:
openjdk version "17.0.20.1" 2026-08-18
Apache Maven 3.6.3
- 网络可达 Maven 中央仓库(
repo.maven.apache.org);无外网环境直接用官方二进制包方案(《Ubuntu 22.04 安装 Apache Commons Lang 指南》第五章),本文第五、七章的java -cp验证同样适用。 - 磁盘空间:commons-lang3 jar 约 750 kB,加 Guava 共存验证建议预留 50 MB。
三、依赖引入(Maven)
在任意 Maven 工程的 pom.xml 中加入以下依赖声明(本文示例工程 /opt/lang-demo/pom.xml 的关键段):
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>17</maven.compiler.release>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.21.0</version>
</dependency>
</dependencies>
两点说明:
project.build.sourceEncoding=UTF-8必须设置:示例代码含中文注释,缺了它在 POSIX locale 下会报unmappable character(实录见《Ubuntu 22.04 安装 Apache Commons Lang 指南》FAQ Q4)。- Common Lang 零传递依赖,引入后不会拖入任何其他版本族,随时用
dependency:tree复核:
cd /opt/lang-demo && mvn -B dependency:tree
输出:
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ lang-demo ---
[INFO] demo:lang-demo:jar:1.0.0
[INFO] \- org.apache.commons:commons-lang3:jar:3.21.0:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
首次构建时 Maven 会自动下载 749 kB 的核心 jar(实测下载速率约 23 kB/s,中央仓库直连约 30 秒到数分钟不等,取决于网络)。
四、10 分钟最小可用:第一个程序
4.1 QuickStart.java 完整代码
创建 /opt/lang-demo/src/main/java/demo/QuickStart.java(全文,覆盖三个最常用 API:null 安全字符串处理、二元元组、区间判断):
package demo;
import org.apache.commons.lang3.Range;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
/** 10 分钟快速入门:StringUtils + Pair + Range 三个最常用 API */
public class QuickStart {
public static void main(String[] args) {
// 1. StringUtils:null 安全的字符串处理
System.out.println("isEmpty(null) = " + StringUtils.isEmpty(null));
System.out.println("isBlank(\" \") = " + StringUtils.isBlank(" "));
System.out.println("join = " + StringUtils.join(new String[]{"a", "b", "c"}, '-'));
System.out.println("capitalize = " + StringUtils.capitalize("hello"));
// 2. Pair:一次携带两个返回值
Pair<String, Integer> user = Pair.of("alice", 30);
System.out.println("pair = " + user);
System.out.println("key = " + user.getKey() + ", value = " + user.getValue());
// 3. Range:区间判断
Range<Integer> range = Range.of(1, 10);
System.out.println("range = " + range);
System.out.println("contains(5) = " + range.contains(5));
System.out.println("fit(15) = " + range.fit(15));
}
}
三段代码分别演示:
- StringUtils:
isEmpty判空(null 安全)、join数组拼接、capitalize首字母大写。 - Pair(注意 import 是
org.apache.commons.lang3.tuple.Pair,tuple 子包):Pair.of构造、getKey/getValue访问。 - Range:
Range.of构造闭区间(between已废弃,见《Apache Commons Lang 3.21.0 进阶 API 与废弃迁移详解》)、contains判断归属、fit把越界值夹进区间。
4.2 编译与运行(Maven 路径)
cd /opt/lang-demo && mvn -B compile
输出节选(实测 compile 段与结尾;实测工程当时含 7 个源文件,读者只建 QuickStart.java 一个文件时显示 Compiling 1 source files 且无 WARNING 属正常):
[INFO] Compiling 7 source files with javac [debug release 17] to target/classes
[WARNING] /opt/lang-demo/src/main/java/demo/RandomDemo.java:[9,74] nextInt(int,int) in org.apache.commons.lang3.RandomUtils has been deprecated
[WARNING] /opt/lang-demo/src/main/java/demo/RandomDemo.java:[10,79] nextDouble(double,double) in org.apache.commons.lang3.RandomUtils has been deprecated
[WARNING] /opt/lang-demo/src/main/java/demo/RandomDemo.java:[11,72] nextBoolean() in org.apache.commons.lang3.RandomUtils has been deprecated
[WARNING] /opt/lang-demo/src/main/java/demo/RandomDemo.java:[14,90] randomAlphabetic(int) in org.apache.commons.lang3.RandomStringUtils has been deprecated
[WARNING] /opt/lang-demo/src/main/java/demo/RandomDemo.java:[15,87] randomNumeric(int) in org.apache.commons.lang3.RandomStringUtils has been deprecated
[WARNING] /opt/lang-demo/src/main/java/demo/TupleRangeDemo.java:[29,33] <T>between(T,T) in org.apache.commons.lang3.Range has been deprecated
[WARNING] /opt/lang-demo/src/main/java/demo/TupleRangeDemo.java:[38,34] <T>between(T,T) in org.apache.commons.lang3.Range has been deprecated
[WARNING] /opt/lang-demo/src/main/java/demo/TupleRangeDemo.java:[41,34] <T>between(T,T) in org.apache.commons.lang3.Range has been deprecated
[WARNING] /opt/lang-demo/src/main/java/demo/StringUtilsDemo.java:[54,75] defaultString(java.lang.String,java.lang.String) in org.apache.commons.lang3.StringUtils has been deprecated
[WARNING] /opt/lang-demo/src/main/java/demo/ExceptionSystemDemo.java:[37,75] <T>defaultIfNull(T,T) in org.apache.commons.lang3.ObjectUtils has been deprecated
[WARNING] /opt/lang-demo/src/main/java/demo/ExceptionSystemDemo.java:[52,46] getValue() in org.apache.commons.lang3.mutable.MutableInt has been deprecated
[INFO] BUILD SUCCESS
QuickStart 自身不调用任何废弃 API,零告警。运行:
cd /opt/lang-demo
CP=target/classes:/root/.m2/repository/org/apache/commons/commons-lang3/3.21.0/commons-lang3-3.21.0.jar
java -Dfile.encoding=UTF-8 -cp $CP demo.QuickStart
输出(实测):
isEmpty(null) = true
isBlank(" ") = true
join = a-b-c
capitalize = Hello
pair = (alice,30)
key = alice, value = 30
range = [1..10]
contains(5) = true
fit(15) = 10
逐行解读:
| 输出 | 解读 |
|---|---|
isEmpty(null) = true | StringUtils 对 null 安全,null 视为空 |
isBlank(" ") = true | 纯空白串也视为空(isEmpty 会返回 false) |
join = a-b-c | 数组用 - 拼接 |
capitalize = Hello | 首字母大写 |
pair = (alice,30) | Pair 的 toString 形态 |
key = alice, value = 30 | Pair 兼容 Map.Entry 的取值方法 |
range = [1..10] | 闭区间 toString 形态 |
contains(5) = true | 5 在 [1,10] 内(闭区间,contains(10) 也是 true) |
fit(15) = 10 | 越界值被夹到上边界 |
看到以上输出,Commons Lang 的引入与使用就全部打通了。API 详解见《Apache Commons Lang 3.21.0 常用 API 与工具类详解》与《Apache Commons Lang 3.21.0 进阶 API 与废弃迁移详解》。
五、javac/java -cp 方式快速验证
不想起 Maven 工程(或在 CI 里做烟测)时,只要有 commons-lang3-3.21.0.jar 就能直跑。jar 来源二选一:Maven 本地仓库(第三步引入后即有)或官方二进制包(《Ubuntu 22.04 安装 Apache Commons Lang 指南》第五章,解压路径 commons-lang3-3.21.0/commons-lang3-3.21.0.jar)。
cd /opt/lang-demo
JAR=/root/.m2/repository/org/apache/commons/commons-lang3/3.21.0/commons-lang3-3.21.0.jar
javac -encoding UTF-8 -cp $JAR -d /tmp/lang-qs-classes src/main/java/demo/QuickStart.java
java -Dfile.encoding=UTF-8 -cp /tmp/lang-qs-classes:$JAR demo.QuickStart
输出(实测,与 4.2 的 Maven 路径逐行一致):
isEmpty(null) = true
isBlank(" ") = true
join = a-b-c
capitalize = Hello
pair = (alice,30)
key = alice, value = 30
range = [1..10]
contains(5) = true
fit(15) = 10
要点:
javac必须带-encoding UTF-8(源码含中文注释),java必须带-Dfile.encoding=UTF-8(含中文输出时才不乱码),两者独立、都要有。- classpath 用冒号分隔(Linux),编译输出目录
/tmp/lang-qs-classes要放在 classpath 最前。 - 官方二进制包内 jar 与 Maven Central 构件 sha256 一致(实测核对见安装指南 5.3),两种来源行为完全相同。
六、编码与 locale 配置
Ubuntu 22.04 默认 locale 为 POSIX,JVM 默认字符集是 ASCII(mvn -v 显示 platform encoding: ANSI_X3.4-1968)。含中文输出的程序不加运行参数会变成问号。用一个最小类实测(/opt/lang-demo/src/main/java/demo/EncodingDemo.java):
package demo;
/** 中文输出编码演示:不含 -Dfile.encoding 时会输出问号 */
public class EncodingDemo {
public static void main(String[] args) {
System.out.println("== 中文输出测试 ==");
System.out.println("结果 = 通过");
}
}
编译后对比两种运行方式:
cd /opt/lang-demo && mvn -B compile
CP=target/classes:/root/.m2/repository/org/apache/commons/commons-lang3/3.21.0/commons-lang3-3.21.0.jar
java -cp $CP demo.EncodingDemo
java -Dfile.encoding=UTF-8 -cp $CP demo.EncodingDemo
输出(实测,前两条命令的回显是问号形态,后一条命令正常):
== ?????? ==
?? = ??
== 中文输出测试 ==
结果 = 通过
配置要点:
- 运行期编码:
java -Dfile.encoding=UTF-8(上例实测修复乱码)。 - 编译期编码:pom 的
project.build.sourceEncoding=UTF-8,或 javac 手工编译时加-encoding UTF-8;缺失时编译含中文源码报unmappable character (0xE6) for encoding US-ASCII(实录见《Ubuntu 22.04 安装 Apache Commons Lang 指南》FAQ Q4)。 - 两处编码互相独立,都要配置;本文所有运行命令统一带
-Dfile.encoding=UTF-8。
七、与 Guava 同 classpath 共存说明
Commons Lang 与 Guava 在实际项目里经常同时引入。两者包名空间完全不同(org.apache.commons.lang3 与 com.google.common),同 classpath 共存没有任何冲突,实测验证如下。
先把 Guava 32.1.3-jre 拉入本地仓库:
mvn -B dependency:get -Dartifact=com.google.guava:guava:32.1.3-jre
ls /root/.m2/repository/com/google/guava/guava/32.1.3-jre/
输出(实测):
_remote.repositories
guava-32.1.3-jre.jar
guava-32.1.3-jre.pom
编写共存验证类 /opt/lang-jars/GuavaCoexistDemo.java(完整,同一程序里两个库各调一组等价 API):
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import org.apache.commons.lang3.StringUtils;
/** Guava 与 Commons Lang 同 classpath 共存验证 */
public class GuavaCoexistDemo {
public static void main(String[] args) {
// Guava 侧
System.out.println("guava Strings.isNullOrEmpty(\"\") = " + Strings.isNullOrEmpty(""));
System.out.println("guava Strings.padStart(\"7\", 3, '0') = " + Strings.padStart("7", 3, '0'));
System.out.println("guava Joiner = " + Joiner.on("|").join("a", "b", "c"));
// Commons Lang 侧
System.out.println("lang3 StringUtils.isBlank(\" \") = " + StringUtils.isBlank(" "));
System.out.println("lang3 StringUtils.leftPad(\"7\", 3, '0') = " + StringUtils.leftPad("7", 3, '0'));
System.out.println("lang3 version = " + StringUtils.class.getPackage().getImplementationVersion());
}
}
编译并运行(两个 jar 同时在 classpath 上):
cd /opt/lang-jars
M2=/root/.m2/repository
javac -encoding UTF-8 -cp $M2/com/google/guava/guava/32.1.3-jre/guava-32.1.3-jre.jar:$M2/org/apache/commons/commons-lang3/3.21.0/commons-lang3-3.21.0.jar -d . GuavaCoexistDemo.java
java -Dfile.encoding=UTF-8 -cp .:$M2/com/google/guava/guava/32.1.3-jre/guava-32.1.3-jre.jar:$M2/org/apache/commons/commons-lang3/3.21.0/commons-lang3-3.21.0.jar GuavaCoexistDemo
输出(实测):
guava Strings.isNullOrEmpty("") = true
guava Strings.padStart("7", 3, '0') = 007
guava Joiner = a|b|c
lang3 StringUtils.isBlank(" ") = true
lang3 StringUtils.leftPad("7", 3, '0') = 007
lang3 version = 3.21.0
结论与注意点:
- 编译与运行均无冲突告警,两库 API 各自正常工作(实测)。
- 语义微差要留意:判空上 Guava 的
Strings.isNullOrEmpty没有纯空白判定(" "返回 false),Commons 的isBlank返回 true(上例实测对比)。 - 补零能力对照:
Strings.padStart("7", 3, '0')与StringUtils.leftPad("7", 3, '0')结果一致(均007),可按既有技术栈任选。 - Maven 工程里共存即各自声明坐标,由 Maven 管理两个 jar;commons-lang3 零传递依赖、guava 单 jar 亦无传递链(failureaccess 等为其 test/编译期依赖),不会产生版本仲裁冲突。
💡 技术拓展:新项目选型建议(何时用 Lang、何时用 Guava/Hutool)——
- 只用基础工具(判空/拼接/反射 equals):Commons Lang 单选即可,零传递依赖、Java 8 兼容面广、API 稳定 20 年,是最保守可靠的默认。
- 重度使用集合/缓存/并发/函数式:引入 Guava,其 Strings/Joiner/Splitter 顺带覆盖字符串场景;此时 Lang 用于 Guava 没有的能力(元组 Pair/Triple、Range、MutableInt、builder 反射系列),两者互补不冲突(本章实测)。
- 快速原型/中小业务系统:Hutool 的中文文档与全家桶封装上手最快;但生态绑定较深,长期维护的大型工程建议回归 Apache/Guava 两家。
- 通用判空约定:混用时统一团队口径(如「输入侧用 Commons isBlank 宽容处理、出参断言用 Guava Preconditions 快速失败」),避免同一语义两套写法。
八、常见错误与解决
错误 1:编译出现 has been deprecated 告警。
原因:调用了 3.21.0 已废弃的 API(4.2 实测工程的告警均来自本系列示例中的旧式调用,QuickStart 本身零告警)。处理:按《Apache Commons Lang 3.21.0 进阶 API 与废弃迁移详解》第十一章总表迁移——重点 Range.between(T,T) 改 Range.of(T,T)、RandomStringUtils 旧静态方法改 insecure()/secure() 工厂 + 实例方法。告警不影响运行,可先用 @Deprecated 排查定位。
错误 2:编译报 cannot find symbol: class Triple。
原因:import 写错包位置——Pair/Triple 在 org.apache.commons.lang3.tuple 子包,不在 lang3 顶层;MutableInt 在 org.apache.commons.lang3.mutable。实测完整报错(把 Triple 写成顶层包时):
/opt/lang-jars/badimport/BadImport.java:1: error: cannot find symbol
import org.apache.commons.lang3.Triple;
^
symbol: class Triple
location: package org.apache.commons.lang3
/opt/lang-jars/badimport/BadImport.java:5: error: cannot find symbol
Triple<String, Integer, Boolean> t = Triple.of("flag", 1, true);
^
symbol: class Triple
location: class BadImport
/opt/lang-jars/badimport/BadImport.java:5: error: cannot find symbol
Triple<String, Integer, Boolean> t = Triple.of("flag", 1, true);
^
symbol: variable Triple
location: class BadImport
3 errors
定位方法是在 jar 里直接搜类名确认包路径:
jar tf /root/.m2/repository/org/apache/commons/commons-lang3/3.21.0/commons-lang3-3.21.0.jar | grep -iE "triple|/Pair"
输出:
org/apache/commons/lang3/tuple/ImmutableTriple.class
org/apache/commons/lang3/tuple/MutableTriple.class
org/apache/commons/lang3/tuple/Pair.class
org/apache/commons/lang3/tuple/Triple.class
错误 3:中文输出变问号 ???。
原因:POSIX locale 下 JVM 默认字符集是 ASCII。实测复现与修复见第六章(java -Dfile.encoding=UTF-8)。编译期还要另配 -encoding UTF-8 或 pom 的 sourceEncoding,两者独立。
错误 4:mvn compile 报 invalid flag: --release。
Maven 实际运行在 JDK 8 上(pom 要求 release 17)。定位与解决(mvn -version 看 Java version: 行、export JAVA_HOME=/usr/lib/jvm/java-17-openjdk)的完整实录见《CentOS 8 安装 Apache Commons Lang 指南》FAQ Q1。另注意:Maven 编译产物必须用 $JAVA_HOME/bin/java 运行,否则报 UnsupportedClassVersionError(同篇 FAQ Q2)。
九、参考链接
- Apache Commons Lang 官方首页(含用户指南):https://commons.apache.org/proper/commons-lang/
- Commons Lang 3.21.0 Javadoc 总览:https://commons.apache.org/proper/commons-lang/javadocs/api-release/index.html
- Maven 中央仓库坐标页:https://repo.maven.apache.org/maven2/org/apache/commons/commons-lang3/
- 常用工具类详解:《Apache Commons Lang 3.21.0 常用 API 与工具类详解》
- 进阶 API 与废弃迁移:《Apache Commons Lang 3.21.0 进阶 API 与废弃迁移详解》
- 环境搭建与排障全流程:《Ubuntu 22.04 安装 Apache Commons Lang 指南》《CentOS 8 安装 Apache Commons Lang 指南》