objects.nonnull()和isnull()用于链式调用中语义化判空,不替代if(obj==null);requirenonnull()是断言工具,抛npe而非提供默认值;equals()安全比较两端可能为null的值;hash()和tostring()对null有默认处理但需注意边界。

Objects.nonNull() 和 Objects.isNull() 怎么用才不踩坑
这两个方法不是为了“替代 if (obj == null)”而存在,而是为了在链式调用、Stream 或 Optional 场景中让空判断更语义化、更易读。直接写 if (Objects.nonNull(obj)) 跟 if (obj != null) 行为完全一样,但多了一次方法调用开销——除非你在写工具类或封装逻辑,否则没必要硬套。
-
Objects.nonNull()返回boolean,适合用在filter()或断言里,比如list.stream().filter(Objects::nonNull).map(...) -
Objects.isNull()是nonNull()的反向封装,Java 8 引入,纯为对称可读;不要因为它“看起来更直白”就优先选它——JVM 不会优化成单指令,底层仍是== null - 注意:它们**不做解引用**,不会触发 NPE;传入
null安全,传入任意非空引用也安全
Objects.requireNonNull() 的真实用途和常见误用
这个方法的核心作用是「主动抛 NPE + 自定义消息」,本质是断言工具,不是空过滤器。它常被误当成“判空并返回默认值”的函数,但其实它只做一件事:不为空就原样返回,为空就炸。
- 典型正确用法:
public void setName(String name) { this.name = Objects.requireNonNull(name, "name must not be null"); } - 错误用法:把它当
Optional.ofNullable(x).orElse(y)用,比如String s = Objects.requireNonNull(str, "default")—— 这里第二个参数是异常消息,不是默认值,运行时 str 为 null 就直接抛异常了 - 有重载版本:
requireNonNull(T obj)(无提示消息)和requireNonNull(T obj, String message),后者推荐,消息能显著缩短排错时间 - 性能上:方法内只是简单判空 + throw,无循环或反射,可放心用于构造函数、setter 等关键入口
Objects.equals() 为什么比 == 和 String.equals() 更省心
它解决的是「两边都可能为 null」时的安全等值比较问题。你不用再写 a == null ? b == null : a.equals(b) 这种三元嵌套。
-
Objects.equals(a, b)内部逻辑就是先判 a 是否为 null,再判 b 是否为 null,最后调a.equals(b);两个 null 视为相等,一 null 一非 null 视为不等 - 对
String有效,对自定义对象也有效——前提是你的equals()方法已正确定义(且最好配合hashCode()) - 注意:它**不处理深层比较**,比如两个 List 内容相同但引用不同,
Objects.equals(list1, list2)仍会返回 true(因为 List.equals() 已实现内容比较),但两个普通对象即使字段全同,若没重写equals(),仍按引用比较 - 别和
Objects.deepEquals()混淆:deepEquals()会递归进数组,适合int[]、Object[]等场景
Objects.hash() 和 Objects.toString() 的边界情况
这两个方法方便,但容易忽略其设计前提:它们面向的是「已知字段非空」或「愿意接受 null 参与计算」的场景。
立即学习“Java免费学习笔记(深入)”;
-
Objects.hash(a, b, c)底层调Arrays.hashCode(Object[]),对每个参数调Objects.hashCode();而Objects.hashCode(null)返回 0 —— 所以如果 a 和 b 都为 null,hash(a, b)和hash(null, null)结果一致,这没问题;但如果你希望 null 字段彻底排除出 hash 计算,就得自己过滤 -
Objects.toString(obj)默认转成"null"字符串;Objects.toString(obj, "default")在 obj 为 null 时返回 "default" —— 这个重载很实用,比如日志拼接:log.info("user={}", Objects.toString(user, "anonymous")) - 它们都不做 toString() 的空保护:如果
obj非 null,但其toString()方法本身抛 NPE(比如内部字段未初始化),Objects.toString(obj)一样会炸
Objects 方法来“显得高级”。空检查逻辑是否该提前抛异常、是否该返回默认值、是否该跳过处理——这些决策比用哪个工具方法重要得多。最容易被忽略的,是把 requireNonNull() 当作防御性编程的万能锤,却忘了业务上有些 null 是合法状态,不该一棍子打死。










