Objects.requireNonNull()用于方法入口强制校验单个参数非空,为null时立即抛NPE;Objects.equals()安全比较两对象,避免左侧为null导致异常;Objects.hash()和toString()简化哈希与字符串生成;nonNull()/isNull()仅作条件判断,不替代显式判空。

Objects.requireNonNull() 是最直接的非空断言
它会在参数为 null 时立即抛出 NullPointerException,而不是等后续调用才崩。适合在方法入口强制校验入参,把问题暴露得早、位置准。
常见错误是误以为它“防止”空指针——其实它不阻止 null 进来,而是主动炸掉,避免静默失败或更难排查的间接 NPE。
- 只校验单个对象,不递归检查字段;
requireNonNull(obj, "user must not be null")可加自定义提示 - 返回原对象,可链式使用:
Objects.requireNonNull(user).getName() - 别在循环里反复调用它做“兜底”,那是设计缺陷,不是防御性编程
Objects.equals() 替代 obj1.equals(obj2) 避免左侧为 null
传统写法 obj1.equals(obj2) 在 obj1 为 null 时直接抛 NPE;而 Objects.equals(a, b) 内部先判空,安全返回 false(除非两者都为 null,则返回 true)。
适用场景:DTO 比较、Map 的 key/value 匹配、JSON 反序列化后字段比对。
立即学习“Java免费学习笔记(深入)”;
- 不要用于性能敏感路径(有两次非空判断 + 一次 equals 调用)
- 注意语义差异:当
a和b都为null时,Objects.equals(a, b)返回true,但a == b也成立;而a.equals(b)此时根本无法执行 - 若已知一方非空(如常量字符串),直接用
"abc".equals(str)更轻量
Objects.hash() 和 Objects.toString() 减少手写模板出错
手写 hashCode() 或 toString() 容易漏字段、错顺序、忘判空,导致哈希不一致或日志打印崩溃。Objects.hash(f1, f2, f3) 和 Objects.toString(obj, "null") 就是为此封装的快捷工具。
它们本身不防 NPE,但能帮你避开因手动处理空值引发的逻辑错误。
-
Objects.hash(name, age, department)自动跳过null字段,不会因某个字段为空导致整个 hash 计算失败 -
Objects.toString(user, "User{?}")在user为null时返回默认字符串,避免user.toString()崩溃 - 注意:这些方法不处理嵌套对象的深层空值,比如
user.getAddress().getCity()仍需你保证getAddress()非空
Objects.nonNull() 和 Objects.isNull() 仅用于条件判断,别滥用
这两个是纯工具函数,返回 boolean,常配合 Stream.filter() 或三元表达式使用,比如 list.stream().filter(Objects::nonNull).map(...)。
它们本身不改变对象状态,也不抛异常,只是让判空逻辑更清晰可读。
- 别写成
if (Objects.nonNull(str)) { str.length(); }—— 直接if (str != null)更直白,无额外开销 - 在 Lambda 中用
Objects::nonNull是合理场景,因为方法引用简洁且语义明确 - 和
requireNonNull()混用要小心:前者是“查”,后者是“拦”,目的不同,不可互相替代
真正容易被忽略的是:Objects 工具类解决的是「显式空值处理」,不是「隐式空值传播」。比如一个方法返回 Optional,你用 Objects.requireNonNull(opt.get()) 就绕过了 Optional 的语义,反而制造了新的风险点。










