Check an replace null values in multiple variables java

14,774

Solution 1

Unless you want to resort to reflection (which I strongly discourage) your best bet is probably to create a helper method (return s == null ? "" : s) and do

field1 = nullToEmpty(field1);
field2 = nullToEmpty(field2);
...

If you already depend on Apache Commons or Guava you can use StringUtils.defaultString or Strings.nullToEmpty.

Solution 2

I agree with aioobe, using reflection is something you should avoid like the plague. But if you are blessed with a project where for example you have to mock a REST interface manually and the objects that come via this interface have tons of Integer, String, Double etc. inside I think you have no other choice.

Here is a generic method that replaces all null pointers it can find in an object with its scalar default values, fills String fields with an empty string and does so recursively if the objects it finds have a parameterless default constructor. Hope this helps other people in the same situation as well.

static void fillNullObjects(Object object) {
    Field[] fields = object.getClass().getDeclaredFields();
    for (Field field : fields) {
        try {
            field.setAccessible(true);
            if (field.get(object) != null) {
                continue;
            }
            else if (field.getType().equals(Integer.class)) {
                field.set(object, 0);
            }
            else if (field.getType().equals(String.class)) {
                field.set(object, "");
            }
            else if (field.getType().equals(Boolean.class)){
                field.set(object, false);
            }
            else if (field.getType().equals(Character.class)) {
                field.set(object, '\u0000');
            }
            else if (field.getType().equals(Byte.class)) {
                field.set(object, (byte) 0);
            }
            else if (field.getType().equals(Float.class)) {
                field.set(object, 0.0f);
            }
            else if (field.getType().equals(Double.class)) {
                field.set(object, 0.0d);
            }
            else if (field.getType().equals(Short.class)) {
                field.set(object, (short) 0);
            }
            else if (field.getType().equals(Long.class)) {
                field.set(object, 0L);
            }
            else if (field.getType().getDeclaredFields().length > 0){
                for (Constructor<?> constructor : field.getClass().getConstructors()) {
                    if (constructor.getParameterTypes().length == 0) {
                        field.set(object, constructor.newInstance());
                        fillNullObjects(field.get(object));
                    }
                }
            }
       } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

Solution 3

public static String checkNull (String inputString){
    if(inputString == null){
         inputString = "";
    }
    return inputString;
}

And just call that whenever you want to check a string.

Solution 4

20 field variables sounds like an egregious case. You should try to avoid explicitly handling that many variables in any situation, or at least factor the code so they are only ever explicitly listed in one place.

A common pattern is to associate each variable with an enumeration, and use the enumeration as a key in a Map with type Enum -> String, or use the enumeration's ordinal as an index into a String array that is sized to the Enumeration value.

Like so:

public enum StringProperties {
    TTL, RECVBUF, SENDBUF, RETRIES, ... ;
}

If you wanted explicit default values, you can couple an enumeration with a number of parameters:

public enum StringProperties {
    TTL ("100"), 
    RECVBUF ("1024"), 
    SENDBUF ("1500"), 
    RETRIES ("10"), 
    ... 
    ;
    public String getDefaultValue() { ... }
}

This strategy means that your code needs minimal modification if you need to add/remove a property, or change a default value.

In your (copy constructor?) case, you can loop over the enumeration values with something like:

for (StringProperties property : StringProperties.values()) {
    if (obj.getProperty(property) != null) {
        // handle present case
        ...
    } else {
        // handle default storage case
        ...
    }
}

Or, like thomas said, you can use a String array on its own, but this assumes that you don't need a way to address each String.

Solution 5

Check out Apache Commons' StringUtils

StringUtils.defaultString(yourString)

This replaces nulls with an empty String. Or you can define your own replacement:

StringUtils.defaultString(null, "foo") // returns "foo"

http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html#defaultString(java.lang.String)

Share:
14,774
user1795370
Author by

user1795370

Updated on June 12, 2022

Comments

  • user1795370
    user1795370 almost 2 years

    I'm trying to find an easy way to perform multiple null checks/ replacements in multiple variables in Java.

    I have an object with about 20 String variables. In the constructor I want to check if any of the variable values are null. If they are null I want to replace them with an empty String. I could perform a series of if statements but I feel like there must be a cleaner way to do this.

  • aioobe
    aioobe over 9 years
    This is better expressed as return inputString == null ? "" : inputString; imo.
  • TheFaster
    TheFaster over 9 years
    @Tom Yes it is. Hammered that one out way too quick. Fixed.
  • Pratham
    Pratham over 2 years
    Really helpful. Thank you