Objects.requireNonNull()用于方法入口参数校验,提前抛出带提示的NullPointerException;Objects.equals()安全比较可能为null的对象;Objects.toString()避免toString()空指针;Objects.hash()辅助实现一致的hashCode。

Objects.requireNonNull() 是最直接的防御式检查
当你需要确保某个参数非 null 时,Objects.requireNonNull() 是首选。它不是“避免”空指针,而是提前暴露问题——在调用栈靠上的位置抛出 NullPointerException,附带可读的提示信息。
常见错误是把它当“兜底容错”用,比如写成:
String name = Objects.requireNonNull(input, "name must not be null");
但 input 本身已是 null,这段代码仍会抛异常。它的作用不是让程序继续运行,而是让失败更早、更明确。
- 适合用在方法入口参数校验(尤其是 public 方法)
- 第二个参数字符串建议具体,如
"user.id cannot be null",而非泛泛的"argument is null" - 注意:它不改变变量值,也不做转换;只是断言 + 抛异常
Objects.equals() 替代 == 和 obj1.equals(obj2) 的安全写法
比较两个可能为 null 的对象是否逻辑相等时,直接调用 a.equals(b) 容易触发空指针;而 a == b 又无法处理语义相等(比如两个不同实例但内容一致的 String)。
立即学习“Java免费学习笔记(深入)”;
Objects.equals(a, b) 内部做了 null 判定:先检查两者是否都为 null(返回 true),再检查是否有一个为 null(返回 false),最后才调用 a.equals(b)。
- 适用于任何重写了
equals()的类,包括自定义类 - 不要用于性能敏感的循环内部——有轻微开销(两次判空 + 方法调用)
- 注意:它不替代
Objects.deepEquals(),后者用于数组内容比较
Objects.toString() 防止日志或拼接时炸掉
打印日志、生成提示文本或做字符串拼接时,常遇到 obj.toString() 空指针。比如 user.getName().toUpperCase() 中 getName() 返回 null,就会崩。
Objects.toString(obj) 默认返回 "null" 字符串;Objects.toString(obj, "N/A") 可指定默认值。
- 比手写
obj == null ? "null" : obj.toString()更简洁、不易漏 - 特别适合调试输出、DTO 转 JSON 前的字段预处理(如 MyBatis 或 Jackson 序列化前兜底)
- 注意:它不解决业务逻辑中本该非空却为空的问题,只是让展示层不挂
Objects.hash() 和 Objects.hashCode() 的一致性陷阱
重写 hashCode() 时,若字段可能为 null,手动计算容易出错(比如 field.hashCode() 直接调用)。Objects.hash(f1, f2, f3) 会自动对每个参数调用 Objects.hashCode(),后者对 null 返回 0。
但要注意:这个组合哈希值必须和你 equals() 的逻辑严格匹配。例如,如果你的 equals() 忽略了某个字段,那 hash() 里也不该包含它。
- 推荐用 IDE 自动生成的
hashCode()(IntelliJ / Eclipse 都支持基于Objects.hash()) - 不要混用:别在
hashCode()里用Objects.hash(),却在equals()里漏判某个字段 - 性能上无明显劣势,但别在高频调用路径(如实时风控规则匹配)里反复构造临时数组
真正容易被忽略的是:这些工具方法不改变数据流的空状态,只帮你更安全地响应它。设计工具类时,优先考虑「明确契约」——比如方法文档写清“此参数不可为 null”,比到处加 requireNonNull 更有效。










