Apache Commons Lang3 BooleanUtils 实用指南
本文基于
org.apache.commons.lang3.BooleanUtils(Commons Lang3 3.20.0),覆盖字符串/整数转布尔、三态判空、逻辑运算、格式化输出等操作,并整理出 6 个最容易踩的坑。文中所有 API 行为均核对过 Apache 官方源码与 Javadoc。
一、BooleanUtils 到底解决什么问题
很多人以为 BooleanUtils 只是"一堆 if 的语法糖",其实它真正的价值来自 Java 的一个语言层面缺陷:布尔值有三态,但 boolean 只能表达两态。
java
boolean b; // 只有 true / false
Boolean bo; // true / false / null ------ 第三态代表"未知"或"未设置"
这个第三态在真实业务里无处不在:
- 数据库
TINYINT(1)字段允许NULL,映射成Boolean后可能是null - 配置文件里某项没写,
getProperty()返回null - HTTP 表单参数缺失,
request.getParameter("agree")返回null - 三方接口的 JSON 字段
null,反序列化成Boolean
一旦直接拆箱,就是 NPE:
java
Boolean flag = getFromDb(); // 可能是 null
if (flag) { ... } // ❌ NullPointerException
if (flag == true) { ... } // ❌ 拆箱比较,同样 NPE
if (!flag) { ... } // ❌ 还是 NPE
BooleanUtils 就是为这个场景而生:所有判空方法都是 null 安全的,所有转换方法都明确规定了 null 的归宿。
二、引入依赖
xml
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.20.0</version>
</dependency>
java
import org.apache.commons.lang3.BooleanUtils;
BooleanUtils和ArrayUtils在同一个包里,引入了commons-lang3就能直接用,无需额外依赖。
三、字符串转布尔:最常用,也最容易出事
3.1 toBoolean(String)
java
BooleanUtils.toBoolean("yes"); // true
BooleanUtils.toBoolean("Y"); // true
BooleanUtils.toBoolean("on"); // true
BooleanUtils.toBoolean("TRUE"); // true
BooleanUtils.toBoolean("1"); // true
BooleanUtils.toBoolean("t"); // true
它到底认哪些字符串?官方 Javadoc 的原文是:
'true','on','y','t','yes'or'1'(case insensitive) will returntrue.'false','off','n','f','no'or'0'(case insensitive) will returnfalse. Otherwise,nullis returned.
完整识别表(大小写完全无关 ,"Y"、"y"、"YES"、"yEs" 都行):
解析为 true |
解析为 false |
|---|---|
true、t |
false、f |
yes、y |
no、n |
on |
off |
1 |
0 |
一共 7 组。除此之外的任何输入都解析不出来,包括很多你以为应该支持的:
java
BooleanUtils.toBoolean("TRUE "); // false ------ 尾随空格,长度变成 5,匹配不上
BooleanUtils.toBoolean(" true"); // false ------ 前导空格同理
BooleanUtils.toBoolean("enabled"); // false
BooleanUtils.toBoolean("enable"); // false
BooleanUtils.toBoolean("oui"); // false ------ 不支持法语
BooleanUtils.toBoolean("是"); // false ------ 不支持中文
这里是全文最大的坑:toBoolean(String) 对无法识别的输入返回 false,而不是抛异常。
它的实现就一行,看懂了就懂为什么:
java
public static boolean toBoolean(final String str) {
return toBooleanObject(str) == Boolean.TRUE;
}
toBooleanObject 解析失败返回 null,null == Boolean.TRUE 是 false,于是**"拼错了"和"配置成了 false"这两种完全不同的情况,被折叠成了同一个结果**。
一个真实的翻车场景:配置文件里写的是 enable_cache = enabled(多打了个 d),程序静默按 false 运行,缓存永远不生效,而你查半天查不出来------因为没有任何报错。
3.2 toBooleanObject(String):需要区分"未知"时用它
java
BooleanUtils.toBooleanObject("on"); // Boolean.TRUE
BooleanUtils.toBooleanObject("off"); // Boolean.FALSE
BooleanUtils.toBooleanObject("maybe"); // null ------ 无法识别
BooleanUtils.toBooleanObject(null); // null
这个方法返回 Boolean(包装类型),因此能表达第三态 。当你需要区分"用户明确选了否"和"用户根本没填"时,必须用它而不是 toBoolean。
官方 Javadoc 给的边界示例很值得记一下:
java
BooleanUtils.toBooleanObject("blue") // null
BooleanUtils.toBooleanObject("true ") // null ------ 尾随空格(长度不对)
BooleanUtils.toBooleanObject("ono") // null ------ 既不匹配 on 也不匹配 no
⚠️ Javadoc 里专门有一句警告:"This method may return
nulland may throw aNullPointerExceptionif unboxed to aboolean."
javaboolean b = BooleanUtils.toBooleanObject("maybe"); // ❌ NPE!null 自动拆箱用
toBooleanObject时,接收变量必须是Boolean而不是boolean。
3.3 严格模式:toBoolean(str, trueString, falseString)
如果你不想让脏数据静默通过,用三参数重载。它会在无法匹配时抛 IllegalArgumentException:
java
BooleanUtils.toBoolean("Y", "Y", "N"); // true
BooleanUtils.toBoolean("N", "Y", "N"); // false
BooleanUtils.toBoolean("X", "Y", "N"); // ❌ IllegalArgumentException
官方 Javadoc 对这两个重载的行为差异有明确说明,可以概括成一句话:
| 方法 | 无法识别时 |
|---|---|
toBoolean(String) |
静默返回 false |
toBoolean(String, String, String) |
抛 IllegalArgumentException |
选型建议:
- 解析用户可控的宽松输入 (表单、搜索词)→ 用
toBoolean(String),宽容降级 - 解析系统配置、内部协议、数据库枚举值→ 用三参数严格版,让脏数据在启动时就炸出来,而不是潜伏到线上
四、整数转布尔
4.1 toBoolean(int)
java
BooleanUtils.toBoolean(1); // true
BooleanUtils.toBoolean(0); // false
BooleanUtils.toBoolean(-1); // true ← 注意!
BooleanUtils.toBoolean(42); // true ← 注意!
实现同样只有一行:
java
public static boolean toBoolean(final int value) {
return value != 0;
}
判定规则是"非 0 即 true",而不是"只有 1 才是 true"。 这点和 C 语言一致,但如果你从数据库 TINYINT 读到的值可能是 2、3、-1,就要留意它都会变成 true。
如果需要"只有特定值才算 true,其他值算异常",用严格版:
java
BooleanUtils.toBoolean(1, 1, 0); // true ------ 只有 1 是 true,只有 0 是 false
BooleanUtils.toBoolean(0, 1, 0); // false
BooleanUtils.toBoolean(2, 1, 0); // ❌ IllegalArgumentException
4.2 toBooleanObject(int / Integer)
java
BooleanUtils.toBooleanObject(1); // Boolean.TRUE
BooleanUtils.toBooleanObject(0); // Boolean.FALSE
Integer nullInt = null;
BooleanUtils.toBooleanObject(nullInt); // null ------ Integer 重载支持 null
// 四参数版:可以自定义哪个值代表 null
BooleanUtils.toBooleanObject(9, 1, 0, 9); // null ------ 9 被指定为"未知"
toBooleanObject(Integer) 的存在很有意义:数据库字段为 NULL 时,MyBatis/JPA 映射出来的 Integer 就是 null,直接转换即可得到 null 语义的 Boolean,不必手写判空。
五、三态判断:isTrue 家族的四象限
这是 BooleanUtils 最该被记住的部分。四个方法,两两成对,但语义并不对称:
java
BooleanUtils.isTrue(boolObj); // Boolean.TRUE.equals(boolObj)
BooleanUtils.isNotTrue(boolObj); // !isTrue(boolObj)
BooleanUtils.isFalse(boolObj); // Boolean.FALSE.equals(boolObj)
BooleanUtils.isNotFalse(boolObj); // !isFalse(boolObj)
完整真值表(建议收藏):
| 方法 | 入参 TRUE |
入参 FALSE |
入参 null |
|---|---|---|---|
isTrue(x) |
true |
false |
false |
isNotTrue(x) |
false |
true |
true |
isFalse(x) |
false |
true |
false |
isNotFalse(x) |
true |
false |
true |
关键结论:isNotTrue(x) ≠ isFalse(x)。 当 x 为 null 时,前者返回 true,后者返回 false。
这个区别在写业务判断时至关重要:
java
Boolean subscribed = user.getSubscribed(); // 可能是 null
// ✅ "只要不是明确订阅了,就走未订阅流程"(null 也算未订阅)
if (BooleanUtils.isNotTrue(subscribed)) { showUpgradeBanner(); }
// ✅ "只有明确取消了才弹挽留"(null 不弹)
if (BooleanUtils.isFalse(subscribed)) { showRetentionDialog(); }
// ✅ "没有明确关闭,就默认开启"(null 视为开启)
if (BooleanUtils.isNotFalse(pushEnabled)) { sendPush(); }
选错方法不会编译报错,也不会在大多数测试用例里暴露------只会在 null 那一小部分数据上出错,是最难查的一类 bug。
把三态压成两态:toBooleanDefaultIfNull
当你确定要给 null 一个默认值时,这个方法比 isNotTrue 更直白:
java
BooleanUtils.toBooleanDefaultIfNull(null, false); // false
BooleanUtils.toBooleanDefaultIfNull(null, true); // true
BooleanUtils.toBooleanDefaultIfNull(Boolean.TRUE, false); // true
BooleanUtils.toBooleanDefaultIfNull(Boolean.FALSE, true); // false
它是唯一能把 Boolean 安全拆箱成 boolean 而不 NPE 的方法,很适合在接口边界处做归一化:
java
public void setUserSetting(Boolean rawValue) {
this.enabled = BooleanUtils.toBooleanDefaultIfNull(rawValue, true); // 默认开启
}
六、取反:negate
java
BooleanUtils.negate(Boolean.TRUE); // Boolean.FALSE
BooleanUtils.negate(Boolean.FALSE); // Boolean.TRUE
BooleanUtils.negate(null); // null ← 注意,不是 true!
negate(null) 返回 null 而非 true,这是正确的设计 :既然 null 表示"未知",那么"未知"取反仍然是"未知"。源码:
java
public static Boolean negate(final Boolean bool) {
if (bool == null) {
return null;
}
return bool.booleanValue() ? Boolean.FALSE : Boolean.TRUE;
}
但这也意味着 negate 之后仍然需要判空,别以为取反完就能直接拆箱:
java
Boolean result = BooleanUtils.negate(maybeNull);
boolean b = result; // ❌ 如果 result 是 null,这里 NPE
boolean safe = BooleanUtils.toBooleanDefaultIfNull(BooleanUtils.negate(maybeNull), false); // ✅
negate(null) == null 和 isNotTrue(null) == true 是两套不同的 null 哲学,同时存在于这个类里,用的时候要看清楚返回类型是 Boolean 还是 boolean:
- 返回
Boolean的方法(negate、toBooleanObject)→ 保留 null 语义 - 返回
boolean的方法(isTrue、isNotTrue、toBoolean)→ 消解 null 语义
七、逻辑运算:and / or / xor / oneHot
7.1 xor 是奇偶校验,不是"有且仅有一个"
java
BooleanUtils.xor(true, false, true); // false
BooleanUtils.xor(true, true, true); // true
BooleanUtils.xor(true, true); // false
官方 Javadoc 的定义说得很清楚:
This behaves like an XOR gate; it returns
trueif the number oftruevalues is odd, andfalseif the number oftruevalues is zero or even.
也就是统计 true 的个数,奇数为 true,偶数(含 0)为 false。
这里有个高频误解:很多人以为 xor(a, b, c) 是"三个里面恰好一个为真"。不是。xor(true, true, true) 返回 true(3 个 true,奇数),但"恰好一个"应该是 false。
如果你要的真是"有且仅有一个为真",用 oneHot:
java
BooleanUtils.oneHot(true, true, true); // false ← 三个都真,不满足"仅一个"
BooleanUtils.oneHot(true, false, false); // true ← 恰好一个
BooleanUtils.oneHot(false, false, false); // false ← 一个都没有
官方 Javadoc 的定义:"returns true if one, and only one, of the supplied values is true."
| 方法 | 语义 | (T,T,T) |
(T,F,F) |
(F,F,F) |
|---|---|---|---|---|
xor |
true 的个数为奇数 | true |
true |
false |
oneHot |
有且仅有一个 true | false |
true |
false |
7.2 and / or
java
BooleanUtils.and(true, true, false); // false ------ 全真才真
BooleanUtils.or(true, false, false); // true ------ 有一真即真
两者都是短路实现 :and 遇到第一个 false 立即返回,or 遇到第一个 true 立即返回,所以传大量参数时不会全量遍历。
7.3 共同的坑:空参数会抛异常
and / or / xor / oneHot 的基本类型版(boolean...)全都 在开头调用了 ObjectUtils.requireNonEmpty(array, "array");Boolean... 版本则通过委托给基本类型版间接触发同样的校验:
java
BooleanUtils.xor(); // ❌ IllegalArgumentException(空数组)
BooleanUtils.and(new boolean[0]); // ❌ IllegalArgumentException
BooleanUtils.xor((boolean[]) null); // ❌ NullPointerException
这在动态构造条件时很容易踩到:
java
// ❌ 反例:conditions 可能为空集合
List<Boolean> conditions = collectConditions();
boolean ok = BooleanUtils.and(conditions.toArray(new Boolean[0])); // 空集合直接抛异常
// ✅ 正确:先兜底
if (conditions.isEmpty()) {
ok = true; // 或按业务定义空集的默认值
} else {
ok = BooleanUtils.and(conditions.toArray(new Boolean[0]));
}
7.4 Boolean 包装类型的重载:null 元素按 false 处理
每个逻辑运算都有 Boolean... 重载,它容忍数组元素为 null:
java
BooleanUtils.xor(Boolean.FALSE, null); // Boolean.FALSE
BooleanUtils.xor(Boolean.TRUE, null); // Boolean.TRUE
官方 Javadoc 说明:"Null array elements map to false." 实现上是委托给 ArrayUtils.toPrimitive(array) 完成的------顺带一提,ArrayUtils.toPrimitive(Boolean[]) 内部会把 null 元素替换成 false,这与 ArrayUtils.toPrimitive(Integer[]) 遇 null 抛 NPE 的行为并不一致,跨工具类使用时要注意。
但注意:元素可以是 null,数组本身不能是 null (xor((Boolean[]) null) 仍抛 NPE)。
八、布尔转其他类型
8.1 转整数:toInteger / toIntegerObject
java
BooleanUtils.toInteger(true); // 1
BooleanUtils.toInteger(false); // 0
// 自定义映射值
BooleanUtils.toInteger(true, 100, 200); // 100
BooleanUtils.toInteger(false, 100, 200); // 200
// 处理三态(含 null)
BooleanUtils.toInteger(null, 1, 0, -1); // -1 ------ null 映射为 -1
// 返回包装类型
BooleanUtils.toIntegerObject(true); // Integer 1
BooleanUtils.toIntegerObject((Boolean) null); // null
写数据库、拼协议报文、做埋点上报时很常用:
java
entity.setStatus(BooleanUtils.toInteger(user.isActive(), 1, 0));
8.2 转字符串:toString 家族
java
BooleanUtils.toString(true, "是", "否"); // "是"
BooleanUtils.toString(false, "是", "否"); // "否"
BooleanUtils.toStringYesNo(true); // "yes"
BooleanUtils.toStringYesNo(false); // "no"
BooleanUtils.toStringOnOff(true); // "on"
BooleanUtils.toStringTrueFalse(true); // "true"
三态版本(Boolean 入参)多一个 null 的映射:
java
BooleanUtils.toStringYesNo(null); // null
BooleanUtils.toString(null, "是", "否", "未知"); // "未知"
这几个方法正好是第 3 节解析方法的逆操作,配合起来可以做配置项的读写:
java
// 写配置
props.setProperty("feature.flag", BooleanUtils.toStringYesNo(enabled));
// 读配置
boolean enabled = BooleanUtils.toBoolean(props.getProperty("feature.flag"));
注意 BooleanUtils 把常用字面量做成了公开常量,拼字符串时可以直接引用,避免手写笔误:
java
BooleanUtils.TRUE // "true"
BooleanUtils.FALSE // "false"
BooleanUtils.YES // "yes"
BooleanUtils.NO // "no"
BooleanUtils.ON // "on"
BooleanUtils.OFF // "off"
8.3 比较:compare
java
BooleanUtils.compare(true, false); // 1 ------ true > false
BooleanUtils.compare(false, true); // -1
BooleanUtils.compare(true, true); // 0
实现了 Comparator 契约,可以直接用于排序:
java
List<Boolean> flags = Arrays.asList(false, true, false);
flags.sort(BooleanUtils::compare); // 升序:false 在前,true 在后
九、完整可运行示例
java
import org.apache.commons.lang3.BooleanUtils;
public class BooleanUtilsDemo {
public static void main(String[] args) {
// ===== 字符串解析 =====
System.out.println(BooleanUtils.toBoolean("yes")); // true
System.out.println(BooleanUtils.toBoolean("Y")); // true
System.out.println(BooleanUtils.toBoolean("maybe")); // false ← 静默降级,最大的坑
System.out.println(BooleanUtils.toBooleanObject("on")); // true
System.out.println(BooleanUtils.toBooleanObject("maybe")); // null ← 能区分"未知"
// ===== 整数解析 =====
System.out.println(BooleanUtils.toBoolean(1)); // true
System.out.println(BooleanUtils.toBoolean(-1)); // true ← 非 0 即 true
// ===== 三态判断 =====
Boolean t = Boolean.TRUE, f = Boolean.FALSE, n = null;
System.out.println(BooleanUtils.isTrue(n)); // false
System.out.println(BooleanUtils.isNotTrue(n)); // true ← null 算"不是 true"
System.out.println(BooleanUtils.isFalse(n)); // false ← 但 null 不算"是 false"
System.out.println(BooleanUtils.isNotFalse(n)); // true
System.out.println(BooleanUtils.toBooleanDefaultIfNull(n, true)); // true ← 安全拆箱
// ===== 取反 =====
System.out.println(BooleanUtils.negate(t)); // false
System.out.println(BooleanUtils.negate(n)); // null ← 保留三态
// ===== 逻辑运算 =====
System.out.println(BooleanUtils.xor(true, false, true)); // false ← 2 个 true,偶数
System.out.println(BooleanUtils.xor(true, true, true)); // true ← 3 个 true,奇数
System.out.println(BooleanUtils.oneHot(true, true, true)); // false ← 不是"仅一个"
System.out.println(BooleanUtils.oneHot(true, false, false)); // true
System.out.println(BooleanUtils.and(true, true, false)); // false
System.out.println(BooleanUtils.or(false, false, true)); // true
// ===== 反向转换 =====
System.out.println(BooleanUtils.toInteger(true)); // 1
System.out.println(BooleanUtils.toStringYesNo(false)); // "no"
System.out.println(BooleanUtils.compare(true, false)); // 1
}
}
十、六个必须知道的坑
坑 1:toBoolean(String) 静默降级,脏数据不会报错
无法识别的字符串(包括 "enabled"、"true "、"是")一律返回 false,不抛异常、不打日志。配置写错时程序照常运行,只是行为不对。
对策 :解析配置文件、内部协议时用三参数严格版 toBoolean(str, trueString, falseString),让它抛 IllegalArgumentException;或在解析后主动校验:
java
Boolean parsed = BooleanUtils.toBooleanObject(raw);
if (parsed == null) {
throw new IllegalArgumentException("非法布尔配置值: " + raw);
}
坑 2:toBooleanObject 的结果不能直接拆箱
java
boolean b = BooleanUtils.toBooleanObject("maybe"); // ❌ NullPointerException
返回类型是 Boolean,赋给 boolean 会触发自动拆箱,而 null 无法拆箱。接收变量必须用 Boolean,或套一层 toBooleanDefaultIfNull。
坑 3:isNotTrue ≠ isFalse
isNotTrue(null) 是 true,isFalse(null) 是 false。四个判断方法对 null 的态度各不相同,见第五节的真值表。选错的代码不会报错,只在 null 数据上出错。
坑 4:xor 是奇偶校验,不是"恰好一个"
xor(true, true, true) 返回 true。想要"有且仅有一个为真",请用 oneHot。
坑 5:and / or / xor / oneHot 不接受空参数
传入空数组抛 IllegalArgumentException,传入 null 数组抛 NullPointerException。从 Collection 动态转数组调用时,务必先判空。
坑 6:toBoolean(int) 是"非 0 即 true"
toBoolean(-1)、toBoolean(42) 都返回 true。如果数据源(如数据库字段)可能出现 1/0 之外的值,且这些值有独立业务含义,请用 toBoolean(value, trueValue, falseValue) 严格版。
十一、速查表
java
// ===== 字符串 → 布尔 =====
BooleanUtils.toBoolean("yes"); // true(认 true/t/yes/y/on/1,大小写无关)
BooleanUtils.toBoolean("maybe"); // false ⚠️ 无法识别时静默降级
BooleanUtils.toBooleanObject("on"); // Boolean.TRUE
BooleanUtils.toBooleanObject("maybe"); // null(能表达"未知",不可直接拆箱)
BooleanUtils.toBoolean("Y", "Y", "N"); // true(严格版,不匹配抛 IllegalArgumentException)
// ===== 整数 → 布尔 =====
BooleanUtils.toBoolean(1); // true(规则是 != 0,-1 也是 true)
BooleanUtils.toBoolean(2, 1, 0); // ❌ IllegalArgumentException(严格版)
BooleanUtils.toBooleanObject(1); // Boolean.TRUE
BooleanUtils.toBooleanObject((Integer) null); // null
// ===== 三态判断(null 安全)=====
BooleanUtils.isTrue(boolObj); // 仅 TRUE 返回 true
BooleanUtils.isNotTrue(boolObj); // FALSE 和 null 都返回 true
BooleanUtils.isFalse(boolObj); // 仅 FALSE 返回 true
BooleanUtils.isNotFalse(boolObj); // TRUE 和 null 都返回 true
BooleanUtils.toBooleanDefaultIfNull(obj, true); // 安全拆箱,null 走默认值
// ===== 取反 =====
BooleanUtils.negate(Boolean.TRUE); // Boolean.FALSE
BooleanUtils.negate(null); // null(保留三态)
// ===== 逻辑运算(空参数会抛异常)=====
BooleanUtils.and(true, true, false); // false,短路
BooleanUtils.or(false, false, true); // true,短路
BooleanUtils.xor(true, false, true); // false,true 个数为奇数则 true
BooleanUtils.oneHot(true, false, false); // true,有且仅有一个 true
// ===== 布尔 → 其他 =====
BooleanUtils.toInteger(true); // 1
BooleanUtils.toInteger(true, 100, 200); // 100
BooleanUtils.toInteger(null, 1, 0, -1); // -1
BooleanUtils.toStringYesNo(true); // "yes"
BooleanUtils.toStringOnOff(false); // "off"
BooleanUtils.toStringTrueFalse(true); // "true"
BooleanUtils.toString(b, "是", "否", "未知"); // 三态版
BooleanUtils.compare(true, false); // 1(true > false)
// ===== 常量 =====
BooleanUtils.TRUE / FALSE / YES / NO / ON / OFF // "true"/"false"/"yes"/"no"/"on"/"off"
十二、其他值得一用的方法
| 方法 | 作用 | 备注 |
|---|---|---|
toBoolean(Boolean) |
Boolean → boolean,null 视为 false |
null 安全拆箱 |
toBooleanObject(Integer) |
Integer → Boolean,null 保持 null |
数据库字段转换 |
toIntegerObject(...) |
转成 Integer 而非 int |
有多个重载 |
primitiveValues() |
返回 boolean[]{false, true} |
|
booleanValues() |
返回 Boolean[]{FALSE, TRUE} |
|
values() |
返回 List<Boolean>,含 FALSE、TRUE |
|
forEach(Consumer<Boolean>) |
遍历两个布尔值 | 3.13.0+ |
toString(bool, t, f) |
自定义字面量输出 | 两参数版不处理 null |
compare(boolean, boolean) |
实现 Comparator 契约 |
可用于排序 |
and(Boolean...) / or(Boolean...) / xor(Boolean...) / oneHot(Boolean...) |
包装类型版逻辑运算 | null 元素按 false 处理 |
顺带一提:
BooleanUtils的公开构造器已标注@Deprecated(官方计划在 4.0 改为 private),它和所有工具类一样只应静态调用,不要new。
十三、小结
BooleanUtils 的设计有一条清晰的主线:让"未知"这个第三态在每一步都有明确归宿。
三条使用原则:
-
区分两态还是三态 。需要保留"未设置"语义就用返回
Boolean的方法(toBooleanObject、negate),需要落地成确定值就用返回boolean的方法(toBoolean、isTrue、toBooleanDefaultIfNull)。混用是 NPE 和逻辑错误的主要来源。 -
区分宽松还是严格 。解析用户输入用宽松版(静默降级),解析系统配置用严格版(
toBoolean(str, trueString, falseString),不匹配即抛异常)。不要让配置错误静默通过,这是本文最想传达的一点。 -
isTrue家族按真值表选 ,不要凭方法名猜语义------isNotTrue和isFalse在null上给出相反答案。
如果你正在处理从数据库、配置文件或三方接口读出来的 Boolean 字段,把散落在代码里的 flag != null && flag 统一替换成 BooleanUtils.isTrue(flag),通常能一次性消除一批潜在 NPE。
参考 :Apache Commons Lang3 BooleanUtils 官方 API 文档 | BooleanUtils 源码