[java] What is the best way to know if all the variables in a Class are null?

This would mean that the class was initialized, but the variables were not set.

A sample Class:

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;
    }
}

The actual class is huge that I prefer not to check if(xyz == null) for each of the variables.

This question is related to java

The answer is


The best way in my opinion is Reflection as others have recommended. Here's a sample that evaluates each local field for null. If it finds one that is not null, method will return 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());
    }
}

I think this is a solution that solves your problem easily: (return true if any of the parameters is not null)

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

return isEmpty;}

Another solution to the same task is:(you can change it to if(isEmpty==0) checks if all the parameters are null.

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

            if (isEmpty > 0) {
                return true;
            } else {
                return false;
            }
    }

Another non-reflective solution for Java 8, in the line of paxdiabo's answer but without using a series of if's, would be to stream all fields and check for nullness:

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

This remains quite easy to maintain while avoiding the reflection hammer.


If you want this for unit testing I just use the hasNoNullFieldsOrProperties() method from assertj

assertThat(myObj).hasNoNullFieldsOrProperties();

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...
                }
}

This can be done fairly easily using a Lombok generated equals and a static EMPTY object:

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);
        }
    }
}

Prerequisites:

  • Default constructor should not be implemented with custom behavior as that is used to create the EMPTY object
  • All fields of the class should have an implemented equals (built-in Java types are usually not a problem, in case of custom types you can use Lombok)

Advantages:

  • No reflection involved
  • As new fields added to the class, this does not require any maintenance as due to Lombok they will be automatically checked in the equals implementation
  • Unlike some other answers this works not just for null checks but also for primitive types which have a non-null default value (e.g. if field is int it checks for 0, in case of boolean for false, etc.)

How about streams?

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.
        }
    });
}

"Best" is such a subjective term :-)

I would just use the method of checking each individual variable. If your class already has a lot of these, the increase in size is not going to be that much if you do something like:

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

Provided you keep everything in the same order, code changes (and automated checking with a script if you're paranoid) will be relatively painless.

Alternatively (assuming they're all strings), you could basically put these values into a map of some sort (eg, HashMap) and just keep a list of the key names for that list. That way, you could iterate through the list of keys, checking that the values are set correctly.