Apache Commons Lang 3.21.0 快速入门与集成示例

Apache Commons Lang 3.21.0 十分钟快速入门,Maven 引入后用一个程序实测 StringUtils、Pair、Range,附 javac/java -cp 直跑、中文编码配置、与 Guava 同 classpath 共存实测与常见错误解决。

Apache Commons LangApache Commons Lang2026/10/15

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,原因与实测对比见第六章。

二、前置条件

  1. 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
  1. 网络可达 Maven 中央仓库(repo.maven.apache.org);无外网环境直接用官方二进制包方案(《Ubuntu 22.04 安装 Apache Commons Lang 指南》第五章),本文第五、七章的 java -cp 验证同样适用。
  2. 磁盘空间: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) = trueStringUtils 对 null 安全,null 视为空
isBlank(" ") = true纯空白串也视为空(isEmpty 会返回 false)
join = a-b-c数组用 - 拼接
capitalize = Hello首字母大写
pair = (alice,30)Pair 的 toString 形态
key = alice, value = 30Pair 兼容 Map.Entry 的取值方法
range = [1..10]闭区间 toString 形态
contains(5) = true5 在 [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)。

九、参考链接

  1. Apache Commons Lang 官方首页(含用户指南):https://commons.apache.org/proper/commons-lang/
  2. Commons Lang 3.21.0 Javadoc 总览:https://commons.apache.org/proper/commons-lang/javadocs/api-release/index.html
  3. Maven 中央仓库坐标页:https://repo.maven.apache.org/maven2/org/apache/commons/commons-lang3/
  4. 常用工具类详解:《Apache Commons Lang 3.21.0 常用 API 与工具类详解》
  5. 进阶 API 与废弃迁移:《Apache Commons Lang 3.21.0 进阶 API 与废弃迁移详解》
  6. 环境搭建与排障全流程:《Ubuntu 22.04 安装 Apache Commons Lang 指南》《CentOS 8 安装 Apache Commons Lang 指南》