50

这意味着该类已初始化,但未设置变量。

一个示例类:

public class User {

    String id = null;
    String name = null;

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

实际的类很大,我不想检查每个变量的 if(xyz == null) 。

4

12 回答 12

87

Java 8 的另一个非反射解决方案,在paxdiabo 的答案行中但不使用一系列if's,将流式传输所有字段并检查是否为空:

return Stream.of(id, name)
        .allMatch(Objects::isNull);

这在避免反射锤的同时仍然很容易维护。

于 2016-10-25T11:36:30.170 回答
49

尝试这样的事情:

public boolean checkNull() throws IllegalAccessException {
    for (Field f : getClass().getDeclaredFields())
        if (f.get(this) != null)
            return false;
    return true;            
}

尽管如果可行的话,检查每个变量可能会更好。

于 2012-09-11T03:15:53.437 回答
18

这可以使用生成的 Lombokequals和静态EMPTY对象相当容易地完成:

import lombok.Data;

public class EmptyCheck {
    public static void main(String[] args) {
        User user1 = new User();

        User user2 = new User();
        user2.setName("name");

        System.out.println(user1.isEmpty()); // prints true
        System.out.println(user2.isEmpty()); // prints false
    }

    @Data
    public static class User {
        private static final User EMPTY = new User();

        private String id;
        private String name;
        private int age;

        public boolean isEmpty() {
            return this.equals(EMPTY);
        }
    }
}

先决条件

  • 默认构造函数不应使用自定义行为来实现,因为它用于创建EMPTY对象
  • 类的所有字段都应该有一个实现equals(内置的 Java 类型通常不是问题,如果是自定义类型,您可以使用 Lombok)

优点

  • 不涉及反射
  • 作为添加到类中的新字段,这不需要任何维护,因为由于 Lombok,它们将在equals实现中自动检查
  • 与其他一些答案不同,这不仅适用于空检查,而且适用于具有非空默认值的原始类型(例如,如果字段是int它检查0,如果是booleanforfalse等)
于 2017-02-12T14:04:18.253 回答
11

如果你想要这个进行单元测试,我只使用hasNoNullFieldsOrProperties()来自的方法assertj

assertThat(myObj).hasNoNullFieldsOrProperties();
于 2020-01-02T19:58:32.270 回答
6

流呢?

public boolean checkFieldsIsNull(Object instance, List<String> fieldNames) {

    return fieldNames.stream().allMatch(field -> {
        try {
            return Objects.isNull(instance.getClass().getDeclaredField(field).get(instance));
        } catch (IllegalAccessException | NoSuchFieldException e) {
            return true;//You can throw RuntimeException if need.
        }
    });
}
于 2018-06-14T12:52:18.967 回答
4

“最佳”是一个如此主观的术语:-)

我只会使用检查每个单独变量的方法。如果您的班级已经有很多这些,那么如果您执行以下操作,则规模的增加不会那么多:

public Boolean anyUnset() {
    if (  id == null) return true;
    if (name == null) return true;
    return false;
}

如果您将所有内容保持在相同的顺序,代码更改(如果您偏执,则使用脚本自动检查)将相对轻松。

或者(假设它们都是字符串),您基本上可以将这些值放入某种类型的映射中(例如,HashMap),然后只保留该列表的键名列表。这样,您可以遍历键列表,检查值是否设置正确。

于 2012-09-11T03:14:30.357 回答
3

我认为最好的方法是其他人推荐的反射。这是一个评估每个本地字段是否为空的示例。如果它找到一个不为空的,方法将返回 false。

public class User {

    String id = null;
    String name = null;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isNull() {
        Field fields[] = this.getClass().getDeclaredFields();
        for (Field f : fields) {
            try {
                Object value = f.get(this);
                if (value != null) {
                    return false;
                }
            }
            catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }


        }
        return true;

    }

    public static void main(String args[]) {
        System.out.println(new User().isNull());
    }
}
于 2012-09-11T03:57:40.123 回答
3

我认为这是一个可以轻松解决您的问题的解决方案:(如果任何参数不为空,则返回 true)

  public boolean isUserEmpty(){ 
boolean isEmpty;
isEmpty =  isEmpty = Stream.of(id,
            name)
        .anyMatch(userParameter -> userParameter != null);

return isEmpty;}

同一任务的另一个解决方案是:(您可以将其更改为 if(isEmpty==0) 检查所有参数是否为空。

public boolean isUserEmpty(){  
       long isEmpty;
            isEmpty = Stream.of(id,
                    name)
                    .filter(userParameter -> userParameter != null).count();

            if (isEmpty > 0) {
                return true;
            } else {
                return false;
            }
    }
于 2019-12-18T12:36:11.100 回答
2
Field[] field = model.getClass().getDeclaredFields();     

for(int j=0 ; j<field.length ; j++){    
            String name = field[j].getName();                
            name = name.substring(0,1).toUpperCase()+name.substring(1); 
            String type = field[j].getGenericType().toString();    
            if(type.equals("class java.lang.String")){   
                Method m = model.getClass().getMethod("get"+name);
                String value = (String) m.invoke(model);    
                if(value == null){
                   ... something to do...
                }
}
于 2012-09-11T03:20:58.953 回答
1

最适合我的是

Stream.of(getClass().getDeclaredMethods()).allMatch(Objects::isNull);

它可以在自定义注解+注解处理器中使用,以自动boolean isNull()在注解类上定义方法。

于 2021-09-16T14:22:34.327 回答
0

如果您想做相反的事情,即检查班级的某些/所有成员是否非非,请检查此答案。

为了确保类的某些成员总是非空的,我们可以@NonNull在类的各个字段上使用 lombok 注解。

import lombok.Data;
import lombok.NonNull;

@Data
public class DataClass {
  @NonNull
  private String data1;
  private int data2;
  @NonNull
  private String data3;
  @NonNull
  private String data4;
  @NonNull
  private String data5;
  private String data6;

 DataClass(String data1,...) {
    // constructor
 }
}
于 2021-09-20T05:58:22.387 回答
0

基于 Irkwz 的回答,但方法不同:

public class SomeClass{

private String field1;
private String field2;
private ComplexField field3;
private String field4;
private Integer field15;

public boolean isNullAllFields() {
    return Stream.of(this.getClass().getDeclaredFields()).anyMatch(element -> (element != null));
}

}

最后,您调用 isNullAllFields 方法来确定对象字段是否为空。

于 2021-10-12T13:02:45.203 回答