1. 引言

本文将介绍四种检查对象所有变量是否为 null 的实现方法,每种方法都有其适用场景和注意事项。

2. 为何需要检查 null 变量

在 Java 中,null 表示变量未指向任何内存地址或未被初始化。关键点:

  • 仅实例变量可为 null,基本类型(如 intdouble)不能为 null
  • 未检查的 null 可能导致 IllegalArgumentExceptionNullPointerException
  • 嵌套对象未初始化时,访问其成员会触发运行时错误

以以下 Car 类为例:

public class Car {
    Integer power;
    Integer year;
}

3. 使用 if 语句

最直接的方式是逐个检查字段。在 Car 类中添加方法:

public boolean allNull() {     
    if (power != null) return false;
    if (year != null) return false;
    return true;
}

测试验证:

@Test
public void givenNullFields_whenCheckForNullsUsingIfs_thenReturnCorrectValue(){
    Car car = new Car();
    assertTrue(car.allNull());
}

⚠️ 缺点: 每新增字段需添加 if 语句,维护成本高。仅适用于字段少且稳定的类。

4. 使用 Stream API

通过 Stream.allMatch() 实现声明式检查:

public boolean allNullV2() {
    return Stream.of(power, year)
      .allMatch(Objects::isNull);
}

测试验证:

@Test
public void givenNullFields_whenCheckForNullsUsingStreams_thenReturnCorrectValue(){
    Car car = new Car();
    assertTrue(car.allNullV2());
}

优点: 新增字段只需在 Stream.of() 中添加参数,比 if 语句更简洁。

5. 使用 Apache Commons 的 ObjectUtils

引入依赖:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>

直接使用 ObjectUtils.allNull()

@Test
public void givenNullFields_whenCheckForNullsUsingApacheCommons_thenReturnCorrectValue(){
    Car car = new Car();      
    assertTrue(ObjectUtils.allNull(car.power, car.year));
}

⚠️ 权衡: 引入外部库解决简单问题需评估必要性,但 API 通用性强。

6. 使用反射 API

创建通用工具类 NullChecker

public class NullChecker {
    public static boolean allNull(Object target) {
        return Arrays.stream(target.getClass()
          .getDeclaredFields())
          .peek(f -> f.setAccessible(true))
          .map(f -> getFieldValue(f, target))
          .allMatch(Objects::isNull);
    }

    private static Object getFieldValue(Field field, Object target) {
        try {
            return field.get(target);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
}

测试验证:

@Test
public void givenNullFields_whenCheckForNullsUsingReflection_thenReturnCorrectValue() {
    Car car = new Car();
    assertTrue(NullChecker.allNull(car));
}

优势: 完全通用,新增字段无需修改检查逻辑
缺陷:

  • 反射破坏封装性,编译期无法发现错误
  • 性能开销较大(运行时处理更多逻辑)

7. 总结

方法 适用场景 维护成本 性能
if 语句 字段极少且稳定的类 最佳
Stream API 字段数量中等的普通类 良好
Apache Commons 已引入该库的项目 良好
反射 API 需要极致通用性的框架级代码 最低 较差

核心建议: 优先选择 Stream API 或 Apache Commons,反射 API 仅在必须通用化时谨慎使用。完整代码示例见 GitHub


原始标题:Check If All the Variables of an Object Are Null