How to check multiple objects for nullity?

Often, I can see a code constructs like following:

if(a == null || b == null || c == null){
//...
}

I wonder if there is any widely used library (Google, Apache, etc.) to check against nullity for multiple objects at once, e.g.:

if(anyIsNull(a, b, c)){
//...
}

or

if(allAreNulls(a, b, c)){
//...
}

UPDATE:

  1. I perfectly know how to write it by myself
  2. I know it can be the result of the poor program structure but it's not a case here
  3. Let's make it more challenging and replace original example with something like this:

    if(a != null && a.getFoo() != null && a.getFoo().getBar() != null){
    //...
    }
    

UPDATE 2:

I've created a pull request for Apache Commons Lang library to fix this gap:

These will be incorporated in commons-lang, version 3.5:

  • anyNotNull (Object... values)
  • allNotNull (Object... values)
67046 次浏览

In Java 8, you could use Stream.allMatch to check whether all of the values match a certain condition, such as being null. Not much shorter, but maybe a bit easier to read.

if (Stream.of(a, b, c).allMatch(x -> x == null)) {
...
}

And analogeously for anyMatch and noneMatch.


About your "more challenging example": In this case, I think there is no way around writing a lazy-evaluated conjunction of null-checks, like the one you have:

if (a != null && a.getFoo() != null && a.getFoo().getBar() != null) {
...
}

Any of the other approaches, using streams, lists, or var-arg methods, would try to evaluate a.getFoo() before a has been tested not to be null. You could use Optional with map and method pointers, that will be lazily evaluated one after the other, but whether this makes it any more readable is debatable and may vary from case to case (particularly for longer class names):

if (Optional.ofNullable(a).map(A::getFoo).map(B::getBar).isPresent()) {
...
}


Bar bar = Optional.ofNullable(a).map(A::getFoo).map(B::getBar).orElse(null);

Another alternative might be to try to access the innermost item, but I have a feeling that this is not considered good practice, either:

try {
Bar bar = a.getFoo().getBar();
...
catch (NullPointerException e) {
...
}

Particularly, this will also catch any other NPEs after accessing that element -- either that, or you have to put only the Bar bar = ... in the try and everything else in another if block after the try, nullifying any (questionable) gains in readability or brevity.


Some languages have a Safe Navigation Operator, but it seems like Java is not one of them. This way, you could use a notation like a?.getFoo()?.getBar() != null, where a?.getFoo() will just evaluate to null if a is null. You could emulate behavior like this with a custom function and a lambda, though, returning an Optional or just a value or null if you prefer:

public static <T> Optional<T> tryGet(Supplier<T> f) {
try {
return Optional.of(f.get());
} catch (NullPointerException e) {
return Optional.empty();
}
}


Optional<Bar> bar = tryGet(() -> a.getFoo().getBar(););

EDIT 2018: As of Apache Commons lang 3.5, there has been ObjectUtils.allNotNull() and ObjectUtils.anyNotNull().


No.

None of Apache Commons Lang (3.4), Google Guava (18) and Spring (4.1.7) provide such a utility method.

You'll need to write it on your own if you really, really need it. In modern Java code, I'd probably consider need for such a construct a code smell, though.

You could also use something like the following method. It allows you to pass as many parameters as you want:

public static boolean isAnyObjectNull(Object... objects) {
for (Object o: objects) {
if (o == null) {
return true;
}
}
return false;
}

You call it with as many parameters as you like:

isAnyObjectNull(a, b, c, d, e, f);

You could do something similar for areAllNull.

public static boolean areAllObjectsNull(Object... objects) {
for (Object o: objects) {
if (o != null) {
return false;
}
}
return true;
}

Note: you could also use the ternary operator instead of if (o == null). The two methods shown here have no error handling. Adjust it to your needs.

You can create a list of you objects and use yourList.contains(null) in it.

List < Object > obList = new ArrayList < Object > ();


String a = null;
Integer b = 2;
Character c = '9';


obList.add(a);
obList.add(b);
obList.add(c);


System.out.println("List is " + obList);


if (obList.contains(null)) {
System.out.println("contains null");
} else {
System.out.println("does not contains null");
}

DEMO

Objects.requireNonNull

It is possible with help of Objects class and its requireNonNull method.

public static void requireNonNull(Object... objects) {
for (Object object : objects) {
Objects.requireNonNull(object);
}
}

Apache commons-lang3 since version 3.11 has method ObjectUtils.allNull(Object... values)

ObjectUtils.allNull(obj1, obj2, obj3);

I was looking for a solution, but I don't have apache as a dependency yet and it felt silly to me to add it just for the allNonNull method. Here is my plain vanilla java solution using Predicate#and() / Predicate#or() like this:

private static boolean allNonNull(A a) {
Predicate<A> isNotNull = Objects::nonNull;
Predicate<A> hasFoo = someA -> someA.foo != null;
Predicate<A> hasBar = someA -> someA.foo.bar != null;
return Optional.ofNullable(a)
.filter(isNotNull.and(hasFoo.and(hasBar)))
.isPresent();
}

Note: for the anyNonNull, simply use the or() method instead of and().

When invoked, would give the following output:

    System.out.println(isValid(new A(new Foo(new Bar())))); // true
System.out.println(isValid(new A(new Foo(null)))); // false
System.out.println(isValid(new A(null))); // false
System.out.println(isValid(null)); // false

Class definitions used:

public static class A {
public A(Foo foo) {
this.foo = foo;
}
Foo foo;
}


public static class Foo {
public Foo(Bar bar) {
this.bar = bar;
}
Bar bar;
}


public static class Bar { }

Simply as that:

Stream.of(a,b,c).allMatch(Objects::nonNull)