66

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.

2
  • 2
    if(id == null) is the best method. Commented Sep 11, 2012 at 3:13
  • Reference fields are initialized to their default value, null, in the absence of an explicit initializer.
    – obataku
    Commented Sep 11, 2012 at 3:21

15 Answers 15

114

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.

6
  • 1
    Is there any way to get the field values eg: Stream.of(id, name), remove null fields and return List of values of not null fields
    – Rinsen S
    Commented Mar 3, 2018 at 13:31
  • 1
    @Rinsen you can use filter() but that's a different question and it's likely to have already been asked on SO.
    – Didier L
    Commented Mar 3, 2018 at 13:39
  • If you're using Spring, it has a nice hasText method. If you need to check if at least one field is not null and has text (not empty), it could look like this(intended as a class method):: Stream.of(field1, field2,...fieldN).anyMatch(StringUtils::hasText);
    – RHronza
    Commented Jul 3 at 13:44
  • @RHronza That one exists for internal use within the Spring framework, I would recommend using the StringUtils of Apache Commons Lang instead, as recommended by Spring’s StringUtils javadoc itself!
    – Didier L
    Commented Jul 3 at 14:49
  • @DidierL: I stated that it is only used with Spring, the advantage is not only null safe, but also empty safe
    – RHronza
    Commented Jul 4 at 14:20
59

Try something like this:

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

Although it would probably be better to check each variable if at all feasible.

7
  • 1
    Performance wise, is this far behind the if(variable==null) method?
    – th3an0maly
    Commented Sep 12, 2012 at 10:07
  • 2
    Yes, it will likely take a lot longer than if (var == null).
    – arshajii
    Commented Sep 12, 2012 at 11:00
  • 6
    @Yar, to make this work for private fields, you should do f.setAccessible(true)
    – Jawa
    Commented Mar 22, 2018 at 18:30
  • 2
    using reflection is quite slow, hide a lot of what is actually done and on a more general thought, it can be a pain to refactor (a field can be marked as unused by your IDE when it is actually via reflection :/ and you will never know it was actually used unless you have good tests or you run your app) Of course this doesn't forbid to use reflection, but if you can use any other option.. go for it
    – minioim
    Commented Aug 8, 2019 at 13:03
  • 2
    It will never too much to say that you need to add f.setAccessible(true) in order to avoid IllegalAccessException on private fields.
    – Ara Kokeba
    Commented Nov 21, 2019 at 20:03
39

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.)
5
  • 1
    This will create an extra object EMPTY along with each object. Will this affect the performance?
    – Sp4Rx
    Commented Mar 5, 2019 at 0:34
  • 4
    Empty is a static field here, so it shouldn't be a problem. Commented Jul 25, 2019 at 17:13
  • 1
    @MartinTarjányi but equals() method in java compares instances and not their field values.. you'll need to override equals() and hashCode(). Commented Jan 15, 2020 at 6:09
  • 4
    that's why I used the lombok annotation Commented Jan 15, 2020 at 6:10
  • I find myself needing to do something similar to the OP’s question and my thoughts turned first to the equals method. I originally thought to have an isEmpty method that compared to a new instance of the class, but I like the idea of using a static final object more. Nice solution!
    – Calvin P.
    Commented Feb 22, 2023 at 11:51
21

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

assertThat(myObj).hasNoNullFieldsOrProperties();
6

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

6
  • 2
    But if I do this, I'm gonna have to edit the method each time I add a field to the class. Besides, a generic method can be put in an abstract class and extended to be used in all other Value Objects
    – th3an0maly
    Commented Sep 12, 2012 at 10:08
  • 4
    Yes, you will. I'm not sure why you think that's a problem. You know what fields you're adding, you have to create setters and getters for them. Adding a simple one extra line of checking is not a lot of extra work.
    – paxdiablo
    Commented Sep 12, 2012 at 10:23
  • 2
    @Birger, if that's what they meant, they should have said that. They've had ample opportunity to change it in the intervening four-or-so years :-) In any case, as others have also suggested, this is a perfectly acceptable method unless your class is so unstable, it's having member variables added or removed massively frequently.
    – paxdiablo
    Commented Sep 14, 2016 at 12:20
  • 1
    I concurr, the classes should not be changed. OP did however write that he'd rather not have to check (variable == null) for each variable, and I sympathize with that. It would be neat to have some general way of checking if fields in any given object are null (or not)
    – birgersp
    Commented Sep 14, 2016 at 15:18
  • 1
    @paxdiablo just as an aside, one argument for a more dynamic approach is when you're converting, say, a DTO to a JPA entity-style object or something. If you don't have a way of dynamically checking for any null properties, it gets harder to write a unit test that will fail when you forget to add a conversion for that new property you just added to the DTO.
    – ebwb
    Commented Apr 16, 2019 at 20:23
6

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.
        }
    });
}
1
  • this is not scalable.
    – saran3h
    Commented Oct 30, 2021 at 6:15
4

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();
    
          return  isEmpty > 0

    }
3

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());
    }
}
3
  • There is no "allNull" method on User
    – Linora
    Commented Dec 10, 2018 at 7:36
  • @DomenicD. Perfect. Commented Dec 14, 2018 at 10:56
  • Reflection is slow. We should not be using reflection unless there is absolutely no other choice. Commented Nov 11, 2020 at 17:16
3

You can use the simple solution:

if(user.equals(new User()){
//your processing goes here
}
1
  • This should be an accepted answer. Works well.
    – bareMetal
    Commented Dec 5, 2023 at 9:07
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...
                }
}
1
  • 1
    Instead of comparing field[j].getGenericType().toString() with "class java.lang.String", you can use a straight-forward check of the actual type, i.e. if(field[j].getType() == String.class) That’s simpler and way more efficient.
    – Holger
    Commented Feb 9, 2023 at 8:13
2

Best for me is

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

It can be used in a custom annotation + annotation processor to automagically define a boolean isNull() method on the annotated classes.

1
  • 1
    This will always be false, as the array returned by getDeclaredMethods() never contains null. You’d have to actually invoke those methods if you want to check whether they return null, but mind that not every method is a getter.
    – Holger
    Commented Feb 9, 2023 at 8:07
1

Based on Irkwz's answer, but a different approach:

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

}

And the end of the day u invoke isNullAllFields method to figure out wheter the object fields are empty.

1
  • 1
    “Based on Irkwz's answer” and similarly pointless. You are not checking the values of the fields but only if the array of Field instances returned by getDeclaredFields() contains null, which is always false. You’d have to actually get() the field’s value before checking. And when accessing private fields, you should use SomeClass.class instead of getClass(), because getClass() may return a subclass.
    – Holger
    Commented Feb 9, 2023 at 8:11
1

Easiest way is to convert the class to a map and get its keys and with stream check if any or all key's values are null or not, you can take input from user as well whether they want to check for specific set of keys only!

Below is the code to check whether any of the key's value has null, you can change stream config to all match or any match as per your requirement

Just replace isNullOrEmpty method i have used with proper null or empty check condition for that particular collection

    public boolean checkIfAnyFieldIsNull(Object instance, Set<String> fields){

        try {
            Map<String, Object> instanceMap = new Gson().fromJson(new GsonBuilder().serializeNulls().create().toJson(instance), Map.class);

            if(!isNullorEmpty(instanceMap)) {
                fields = isNullorEmpty(fields) ? instanceMap.keySet() : fields;
                return fields.stream().anyMatch(curField -> isNull(instanceMap.get(curField)));
            }else{
                return false;
            }
        }catch (Exception e){
            return false;
        }
    }
}
0

If you want to do the opposite i.e check if some/all members of class are non-non, the check this answer.

In order to make sure that certain members of the class are always non-null, we can use lombok @NonNull annotation on the individual fields of the class.

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

Try this method once, its works for me!!

private fun checkIfAnyDataIsNull(model: YourModelCass): Boolean {
    return Stream.of<Any>(
        model.date,
        model.merchantName,
        model.payment,
    ).allMatch(Objects::isNull)
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.