1. 引言
java.util.Objects
类自 Java 1.7 版本起成为标准库的一部分。这个类提供了处理对象的静态工具方法,用于执行日常任务,例如对象相等性检查、空值检测等。
本文将深入探讨 Java 9 在 java.util.Objects
类中新增的方法,这些工具方法能帮你写出更简洁健壮的代码。
2. requireNonNullElse
方法
这个方法接收两个参数:当第一个参数非 null
时返回它,否则返回第二个参数。如果两个参数都是 null
,则抛出 NullPointerException
。
private List<String> aMethodReturningNullList(){
return null;
}
@Test
public void givenNullObject_whenRequireNonNullElse_thenElse() {
List<String> aList = Objects.<List>requireNonNullElse(
aMethodReturningNullList(), Collections.EMPTY_LIST);
assertThat(aList, is(Collections.EMPTY_LIST));
}
private List<String> aMethodReturningNonNullList() {
return List.of("item1", "item2");
}
@Test
public void givenObject_whenRequireNonNullElse_thenObject() {
List<String> aList = Objects.<List>requireNonNullElse(
aMethodReturningNonNullList(), Collections.EMPTY_LIST);
assertThat(aList, is(List.of("item1", "item2")));
}
@Test(expected = NullPointerException.class)
public void givenNull_whenRequireNonNullElse_thenException() {
Objects.<List>requireNonNullElse(null, null);
}
✅ 核心特点:
- 简单粗暴的空值处理方案
- 适用于需要默认值的场景
- 双空值时直接抛出异常
3. requireNonNullElseGet
方法
这个方法与 requireNonNullElse
类似,但第二个参数是 java.util.function.Supplier
接口,支持延迟初始化。Supplier
实现负责返回非空对象:
@Test
public void givenObject_whenRequireNonNullElseGet_thenObject() {
List<String> aList = Objects.<List>requireNonNullElseGet(
null, List::of);
assertThat(aList, is(List.of()));
}
⚠️ 使用注意:
- 当默认值创建成本较高时,延迟初始化能提升性能
- 避免在 Supplier 中抛出异常(除非你故意设计)
- 适用于需要动态生成默认值的场景
4. checkIndex
方法
用于检查索引是否在有效范围内(0 <= index < length
)。返回索引本身,否则抛出 IndexOutOfBoundsException
:
@Test
public void givenNumber_whenInvokeCheckIndex_thenNumber() {
int length = 5;
assertThat(Objects.checkIndex(4, length), is(4));
}
@Test(expected = IndexOutOfBoundsException.class)
public void givenOutOfRangeNumber_whenInvokeCheckIndex_thenException() {
int length = 5;
Objects.checkIndex(5, length);
}
❌ 常见踩坑:
- 边界值检查容易出错(
length
本身是非法值) - 比手写
if(index < 0 || index >= length)
更简洁 - 异常信息自动包含边界值,便于调试
5. checkFromToIndex
方法
检查子范围 [fromIndex, toIndex)
是否在 [0, length)
范围内。若子范围有效,返回下界:
@Test
public void givenSubRange_whenCheckFromToIndex_thenNumber() {
int length = 6;
assertThat(Objects.checkFromToIndex(2,length,length), is(2));
}
@Test(expected = IndexOutOfBoundsException.class)
public void givenInvalidSubRange_whenCheckFromToIndex_thenException() {
int length = 6;
Objects.checkFromToIndex(2,7,length);
}
📝 数学表示说明:
[a, b)
表示包含 a 但不包含 b 的范围- 方括号
[]
表示包含值,圆括号()
表示排除值 - 这个方法特别适合验证数组/集合的子范围操作
6. checkFromIndexSize
方法
与 checkFromToIndex
类似,但用 size
替代 toIndex
。子范围表示为 [fromIndex, fromIndex + size)
,需确保在 [0, length)
范围内:
@Test
public void givenSubRange_whenCheckFromIndexSize_thenNumber() {
int length = 6;
assertThat(Objects.checkFromIndexSize(2,3,length), is(2));
}
@Test(expected = IndexOutOfBoundsException.class)
public void givenInvalidSubRange_whenCheckFromIndexSize_thenException() {
int length = 6;
Objects.checkFromIndexSize(2, 6, length);
}
✅ 适用场景:
- 处理分页查询(
offset + limit
验证) - 批量操作时的范围检查
- 比
checkFromToIndex
更符合某些业务逻辑
7. 总结
Java 9 对 java.util.Objects
的扩展展示了 JDK 持续进化的决心。自 Java 7 引入以来,这个工具类一直在稳步增强,新增的方法覆盖了空值处理和边界检查等高频场景。
这些工具方法虽然简单,但能显著减少样板代码。建议在日常开发中优先使用它们,而不是重复造轮子。
本文代码示例可在 GitHub 仓库 获取完整实现。