
Objects.nonNull() 和 Objects.isNull() 怎么选?
直接用 Objects.nonNull(obj) 判断非空,语义清晰、逻辑直白;Objects.isNull(obj) 虽然存在,但容易引发双重否定困惑(比如 !Objects.isNull(obj)),和 Objects.nonNull(obj) 功能完全一样,却多绕一层——多数时候没必要。
常见错误现象:在 Stream 链式调用里写 filter(x -> !Objects.isNull(x)),既啰嗦又难读。
- 推荐写法:
list.stream().filter(Objects::nonNull).map(...) - 适合用
isNull()的场景:强调“必须为空”的校验,比如配置项明确要求某字段留空时才合法 - 两者性能无差异,都是单次引用比较,但可读性差距明显
Objects.equals(a, b) 为什么比 a.equals(b) 更安全?
Objects.equals(a, b) 内部先判空再委托 a.equals(b),天然规避 NullPointerException;而手写 a.equals(b) 一旦 a 为 null 就直接崩。
使用场景:DTO 比较、Map 键匹配、单元测试断言——只要两个对象可能为 null,就该无脑用它。
立即学习“Java免费学习笔记(深入)”;
-
Objects.equals(null, null)→true -
Objects.equals("a", null)→false -
Objects.equals(1, 1L)→false(类型不同,不自动拆箱/转型) - 它不替代重写
equals(),只是帮你安全调用已有逻辑
requireNonNull 系列方法怎么用才不踩坑?
Objects.requireNonNull(obj) 是“快速失败”的标准姿势,比手写 if (obj == null) throw new NullPointerException() 简洁且自带堆栈上下文;带消息的重载还能精准定位问题。
容易踩的坑:用字符串拼接传参,导致异常未抛出时也执行了计算(比如含 DB 查询或 IO)。
- 推荐写法:
Objects.requireNonNull(id, () -> "User ID not found: " + loadFromDB())(Supplier版本,延迟求值) -
requireNonNullElse(obj, defaultValue)可替代三元表达式obj != null ? obj : def,泛型推导更稳 - Java 9+ 才有
requireNonNullElse,低版本需自行封装或用 Optional
Objects.hashCode() 和 Objects.hash() 有什么本质区别?
Objects.hashCode(obj) 是对单个对象的 hashCode() 的空安全封装;Objects.hash(a, b, c) 是对多个值统一哈希,常用于重写 hashCode() 方法。
关键陷阱:误用 Objects.hash(obj) 替代 Objects.hashCode(obj),结果完全不同——前者把整个 obj 当作一个元素塞进可变参数数组,后者才是真调用对象自身的哈希逻辑。
-
Objects.hashCode(null)→0 -
Objects.hash(name, age, address)≈ 手动写31 * (31 * Objects.hashCode(name) + Objects.hashCode(age)) + Objects.hashCode(address) - 重写
hashCode()时,字段含null可放心传给Objects.hash(),它内部已做空处理
最常被忽略的是:这些方法都依赖对象自身 equals() 和 hashCode() 的实现质量。工具类再好,也不能补救没重写的实体类——该重写的 equals 和 hashCode,一个都不能少。










