How to check multiple objects for nullity? - java

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:
I perfectly know how to write it by myself
I know it can be the result of the poor program structure but it's not a case here
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:
Issue: https://issues.apache.org/jira/browse/LANG-781
PR: https://github.com/apache/commons-lang/pull/108
These will be incorporated in commons-lang, version 3.5:
anyNotNull (Object... values)
allNotNull (Object... values)

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.

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)

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

Related

Multi threaded issue with myMethod()

I came across this question and I am trying to figure out the answer.
This is the question:
Assuming a threaded environment, and without knowing anything else, what is the potential problem with myMethod()? How can we fix it in the simplest way?
What is the issue with myMethod?
public class DummyTest {
private static final String FUBAR = "fubar";
public boolean myMethod(final MyObject bar) {
if (bar.getFoo() != null) {
return bar.getFoo().equals(FUBAR);
} else {
return false;
}
}
public interface MyObject {
String getFoo();
void setFoo(String o);
}
}
You are checking bar.getFoo() twice which in multi threaded environment can have different results. MyObject is an interface which its methods can be not synchronized .
You also need to add null check for bar and you don't need null check for bar.getFoo() if you change you code (see below)
You can replace with one liner method:
return bar != null && FUBAR.equals(bar.getFoo());
Or with ternary conditional operator
return bar == null ? false : FUBAR.equals(bar.getFoo());
(In addition to bar potentially being null).
Potentially, bar.getFoo() could return different values on multiple invocations.
Only read it once; and check it for equality with FUBAR in a null-safe way:
return Objects.equals(bar.getFoo(), FUBAR);
// or
return FUBAR.equals(bar.getFoo());
Beside the obvious where bar may be null, the double call to bar.getFoo() is problematic. If we assume that other threads are running, then bar may be changed between the two calls to bar.getFoo() and return two different strings.
A solution would be to call bar.getFoo() only once and save the returned String as a local variable.
public boolean myMethod(final MyObject bar) {
if (bar == null)
return false;
String foo = bar.getFoo();
if (foo != null) {
return foo.equals(FUBAR);
} else {
return false;
}
}
Note: Even in non-multithreaded environment, bar.getFoo() may return different values for every call.

How to compare an Integer using least code?

There is an Integer property called foo in a model. Now I need to know whether it equals 1 or 2. Usually I use:
if (null != model) {
Integer foo = model.getFoo();
if (foo != null) {
if (foo == 1) {
// do something...
}
if (foo == 2) {
// do something...
}
}
}
Is there any handier code to avoid the NullPointerException?
You can use Optional:
Optional.ofNullable(model)
.map(Model::getFoo)
.ifPresent(foo -> {
switch (foo) { // or if-else-if, the important thing is you skip the null check
case 1:
...
break;
case 2:
...
break;
...
}
});
You can use the null-safe java.util.Object.equals:
if(null != model) {
Integer foo = model.getFoo();
if(Objects.equals(foo, 1){
//do something
}
if(Objects.equals(foo, 2){
//do something
}
}
The method has this description:
Returns true if the arguments are equal to each other and false otherwise. Consequently, if both arguments are null, true is returned and if exactly one argument is null, false is returned. Otherwise, equality is determined by using the equals method of the first argument.
If you didn't return null sentinels values, and instead used Optionals, you could do:
Optional<Model> model = getModel();
Optional<Integer> foo = model.flatMap(Model::getFoo);
foo.filter(Integer.valueOf(1)::equals).ifPresent(this::doSomething);
foo.filter(Integer.valueOf(2)::equals).ifPresent(this::doSomethingElse);
You could do Integer.of(1).equals(foo), but this is a bit silly. Why save the one line? I'd just put it inside the same if/else-if chain (and if that gets long, conside a switch/case (which also is not null-safe, though).
if (foo == null)
else if (foo == 1)
else if (foo == 2)
Also note that comparing objects with == is a bit tricky because of how auto-boxing works (or does not work). I think that it works in this case, but I do not want to have to think about it too hard, so in my code I usually drop down to int (after the null check) to be on the safe side.
Assuming possible value is only 1 or 2
Of course the model the should be guarded with null check
Use ternary operator
Model theModel = model.getFoo() ;
if(model!=null && model.getFoo()!=null){
model.getFoo() == 1 ? callOne() : call2();
}
Edit the code to like this:
if (null != model) {
Integer foo = model.getFoo();
if (Integer.valueOf(1).equals(foo)) {
// do something...
}
if (Integer.valueOf(2).equals(foo)) {
// do something...
}
}
I hope to help you.

Does java have some convention to indicate that object is in empty state?

Of course, empty definition can differ. I'm used to PHP's empty though, which calls empty everything that evaluates to false. I'd like to call these things empty in my Java application:
null
String of zero length
0 Integer, Float or Double
false
Any array of zero length
Empty ArrayList or HashMap
Java has, for example, toString convention. Every object is granted to give you some string representation. In my Settings class I operate with HashMap<String, Object>. My empty method looks now like this:
public boolean empty(String name) {
Object val = settings.get(name);
if(val!=null) {
return false;
}
return true;
}
I'd like to extend it in a conventional manner, rather than if(val instanceof XXX) chain.
No, there is no standard convention for this in Java. Also, in Java there is no such thing as "evaluate to false" (except for booleans and Booleans, of course).
You will have to write a method (or rather, a series of overloaded methods for each type you need it for) which implements your notion of "empty". For example:
public static boolean isEmpty(String s) {
return (s == null) || (s.isEmpty());
}
public static boolean isEmpty(int i) {
return i == 0;
}
...
You could use overloading to describe all the "empty" objects:
public static boolean empty(Object o) {
return o == null;
}
public static boolean empty(Object[] array) {
return array == null || array.length == 0;
}
public static boolean empty(int[] array) { //do the same for other primitives
return array == null || array.length == 0;
}
public static boolean empty(String s) {
return s == null || s.isEmpty();
}
public static boolean empty(Number n) {
return n == null || n.doubleValue() == 0;
}
public static boolean empty(Collection<?> c) {
return c == null || c.isEmpty();
}
public static boolean empty(Map<?, ?> m) {
return m == null || m.isEmpty();
}
Examples:
public static void main(String[] args) {
Object o = null;
System.out.println(empty(o));
System.out.println(empty(""));
System.out.println(empty("as"));
System.out.println(empty(new int[0]));
System.out.println(empty(new int[] { 1, 2}));
System.out.println(empty(Collections.emptyList()));
System.out.println(empty(Arrays.asList("s")));
System.out.println(empty(0));
System.out.println(empty(1));
}
AFAIK there is no such convention. It's fairly common to see project specific utility classes with methods such as:
public static boolean isEmpty(String s) {
return s == null || s.isEmpty();
}
However I personally think its use is a bit of a code smell in Java. There's a lot of badly written Java around, but well written Java shouldn't need null checks everywhere, and you should know enough about the type of an object to apply type-specific definitions of "empty".
The exception would be if you were doing reflection-oriented code that worked with Object variables who's type you don't know at compile time. That code should be so isolated that it's not appropriate to have a util method to support it.
Python's duck-typing means the rules are sort of different.
How about creating an interface EmptinessComparable or something similar, and having all your classes implement that? So you can just expect that, and not have to ask instanceof every time.
Java does not, but Groovy does. Groovy runs on the Java VM alongside Java code and provides many shortcuts and convenient conventions such as this. A good approach is write foundation and crital project components in Java and use Groovy for less critical higher level components.
If you want to use the one approach, I would overload a utility method:
public class MyUtils {
public static boolean isEmpty(String s) {
return s == null || s.isEmpty();
}
public static boolean isEmpty(Boolean b) {
return b == null || !b;
}
// add other versions of the method for other types
}
Then your code always looks like:
if (MyUtils.isEmpty(something))
If the type you're checking isn't supported, you'll get a compiler error, and you can implement another version as you like.
There are ways to establish the notion of emptiness but it's not standardized across all Java classes. For example, the Map (implementation) provides the Map#containsKey() method to check if a key exists or not. The List and String (implementations) provide the isEmpty() method but the List or String reference itself could be null and hence you cannot avoid a null check there.
You could however come up with a utility class of your own that takes an Object and using instanceof adapts the empty checks accordingly.
public final class DataUtils {
public static boolean isEmpty(Object data) {
if (data == null) {
return false;
}
if (data instanceof String) {
return ((String) data).isEmpty();
}
if (data instanceof Collection) {
return ((Collection) data).isEmpty();
}
}
}
The Guava Libraries already contains Defaults class that do just that.
Calling defaultValue will return the default value for any primitive type (as specified by the JLS), and null for any other type.
You can use it like shown below:
import com.google.common.base.Defaults;
Defaults.defaultValue(Integer.TYPE); //will return 0
Below is example code on how to use it:
import com.google.common.base.Defaults;
public class CheckingFieldsDefault
{
public static class MyClass {
private int x;
private int y = 2;
}
public static void main() {
MyClass my = new MyClass();
System.out.println("x is defualt: " + (my.x == Defaults.defaultValue(box(my.x).TYPE)));
System.out.println("y is defualt: " + (my.y == Defaults.defaultValue(box(my.y).TYPE)));
}
private static <T extends Object> T box(T t) {
return t;
}
}

Evaluating multiple variable together in if condition

I was wondering whether its possible in java to evaluate multiple variables together in if-else condition like in python.
actual code
if(abc!=null && xyz!=null)
{//...}
dummy code
if(abc && xyz !=null)
{// will it be possible}
FIRST DRAFT
You can write smth like this:
boolean notNull(Object item) {
return item != null;
}
then you could use it like:
if (notNull(abc) && notNull(xyz)) {
//...
}
UPDATE 1:
I came up with a new idea, write function using varargs like:
boolean notNull(Object... args) {
for (Object arg : args) {
if (arg == null) {
return false;
}
}
return true;
}
usage: (you can pass to function multiple arguments)
if (notNull(abc, xyz)) {
//...
}
UPDATE 2:
The best approach is to use library apache commons ObjectUtils,
it contains several ready to use methods like:
allNotNull(Object... values),
anyNotNull(Object... values)
or firstNonNull(T... values)
the only way this would work is if abc was a boolean (and it wouldn't do what you're hoping it would do, it would simply test if abc == true). There is no way to compare one thing to multiple things in Java.
It's Impossible in java, you can use Varargs:
public boolean checkAnything(Object args...){
for(Object obj args){
if(...)
}
return ....;
}
See also:
Varargs
String… parameter in Java
Its not possible to that in Java. Instead you can do something like this:-
public boolean checkForNulls(Object... args){
List<Object> test = new ArrayList<Object>(Arrays.asList(args));
return test.contains(null); // Check if even 1 of the objects was null.
}
If any of the items is null, then the method will return true, else it'll return false. You can use it as per your requirements.
IMHO First is the better way and possible way.
Coming to second way ..if they are boolean values
if(abc && xyz )
{//...}

Java: avoid checking for null in nested classes (Deep Null checking)

Imagine I have a class Family. It contains a List of Person. Each (class) Person contains a (class) Address. Each (class) Address contains a (class) PostalCode. Any "intermediate" class can be null.
So, is there a simple way to get to PostalCode without having to check for null in every step? i.e., is there a way to avoid the following daisy chaining code? I know there's not "native" Java solution, but was hoping if anyone knows of a library or something. (checked Commons & Guava and didn't see anything)
if(family != null) {
if(family.getPeople() != null) {
if(family.people.get(0) != null) {
if(people.get(0).getAddress() != null) {
if(people.get(0).getAddress().getPostalCode() != null) {
//FINALLY MADE IT TO DO SOMETHING!!!
}
}
}
}
}
No, can't change the structure. It's from a service I don't have control over.
No, I can't use Groovy and it's handy "Elvis" operator.
No, I'd prefer not to wait for Java 8 :D
I can't believe I'm the first dev ever to get sick 'n tired of writing code like this, but I haven't been able to find a solution.
You can use for:
product.getLatestVersion().getProductData().getTradeItem().getInformationProviderOfTradeItem().getGln();
optional equivalent:
Optional.ofNullable(product).map(
Product::getLatestVersion
).map(
ProductVersion::getProductData
).map(
ProductData::getTradeItem
).map(
TradeItemType::getInformationProviderOfTradeItem
).map(
PartyInRoleType::getGln
).orElse(null);
Your code behaves the same as
if(family != null &&
family.getPeople() != null &&
family.people.get(0) != null &&
family.people.get(0).getAddress() != null &&
family.people.get(0).getAddress().getPostalCode() != null) {
//My Code
}
Thanks to short circuiting evaluation, this is also safe, since the second condition will not be evaluated if the first is false, the 3rd won't be evaluated if the 2nd is false,.... and you will not get NPE because if it.
If, in case, you are using java8 then you may use;
resolve(() -> people.get(0).getAddress().getPostalCode());
.ifPresent(System.out::println);
:
public static <T> Optional<T> resolve(Supplier<T> resolver) {
try {
T result = resolver.get();
return Optional.ofNullable(result);
}
catch (NullPointerException e) {
return Optional.empty();
}
}
REF: avoid null checks
The closest you can get is to take advantage of the short-cut rules in conditionals:
if(family != null && family.getPeople() != null && family.people.get(0) != null && family.people.get(0).getAddress() != null && family.people.get(0).getAddress().getPostalCode() != null) {
//FINALLY MADE IT TO DO SOMETHING!!!
}
By the way, catching an exception instead of testing the condition in advance is a horrible idea.
I personally prefer something similar to:
nullSafeLogic(() -> family.people.get(0).getAddress().getPostalCode(), x -> doSomethingWithX(x))
public static <T, U> void nullSafeLogic(Supplier<T> supplier, Function<T,U> function) {
try {
function.apply(supplier.get());
} catch (NullPointerException n) {
return null;
}
}
or something like
nullSafeGetter(() -> family.people.get(0).getAddress().getPostalCode())
public static <T> T nullSafeGetter(Supplier<T> supplier) {
try {
return supplier.get();
} catch (NullPointerException n) {
return null;
}
}
Best part is the static methods are reusable with any function :)
You can get rid of all those null checks by utilizing the Java 8 Optional type.
The stream method - map() accepts a lambda expression of type Function and automatically wraps each function result into an Optional. That enables us to pipe multiple map operations in a row. Null checks are automatically handled under the neath.
Optional.of(new Outer())
.map(Outer::getNested)
.map(Nested::getInner)
.map(Inner::getFoo)
.ifPresent(System.out::println);
We also have another option to achieve the same behavior is by utilizing a supplier function to resolve the nested path:
public static <T> Optional<T> resolve(Supplier<T> resolver) {
try {
T result = resolver.get();
return Optional.ofNullable(result);
}
catch (NullPointerException e) {
return Optional.empty();
}
}
How to invoke new method? Look below:
Outer obj = new Outer();
obj.setNested(new Nested());
obj.getNested().setInner(new Inner());
resolve(() -> obj.getNested().getInner().getFoo())
.ifPresent(System.out::println);
Instead of using null, you could use some version of the "null object" design pattern. For example:
public class Family {
private final PersonList people;
public Family(PersonList people) {
this.people = people;
}
public PersonList getPeople() {
if (people == null) {
return PersonList.NULL;
}
return people;
}
public boolean isNull() {
return false;
}
public static Family NULL = new Family(PersonList.NULL) {
#Override
public boolean isNull() {
return true;
}
};
}
import java.util.ArrayList;
public class PersonList extends ArrayList<Person> {
#Override
public Person get(int index) {
Person person = null;
try {
person = super.get(index);
} catch (ArrayIndexOutOfBoundsException e) {
return Person.NULL;
}
if (person == null) {
return Person.NULL;
} else {
return person;
}
}
//... more List methods go here ...
public boolean isNull() {
return false;
}
public static PersonList NULL = new PersonList() {
#Override
public boolean isNull() {
return true;
}
};
}
public class Person {
private Address address;
public Person(Address address) {
this.address = address;
}
public Address getAddress() {
if (address == null) {
return Address.NULL;
}
return address;
}
public boolean isNull() {
return false;
}
public static Person NULL = new Person(Address.NULL) {
#Override
public boolean isNull() {
return true;
}
};
}
etc etc etc
Then your if statement can become:
if (!family.getPeople().get(0).getAddress().getPostalCode.isNull()) {...}
It's suboptimal since:
You're stuck making NULL objects for every class,
It's hard to make these objects generic, so you're stuck making a null-object version of each List, Map, etc that you want to use, and
There are potentially some funny issues with subclassing and which NULL to use.
But if you really hate your == nulls, this is a way out.
Although this post is almost five years old, I might have another solution to the age old question of how to handle NullPointerExceptions.
In a nutshell:
end: {
List<People> people = family.getPeople(); if(people == null || people.isEmpty()) break end;
People person = people.get(0); if(person == null) break end;
Address address = person.getAddress(); if(address == null) break end;
PostalCode postalCode = address.getPostalCode(); if(postalCode == null) break end;
System.out.println("Do stuff");
}
Since there is a lot of legacy code still in use, using Java 8 and Optional isn't always an option.
Whenever there are deeply nested classes involved (JAXB, SOAP, JSON, you name it...) and Law of Demeter isn't applied, you basically have to check everything and see if there are possible NPEs lurking around.
My proposed solution strives for readibility and shouldn't be used if there aren't at least 3 or more nested classes involved (when I say nested, I don't mean Nested classes in the formal context). Since code is read more than it is written, a quick glance to the left part of the code will make its meaning more clear than using deeply nested if-else statements.
If you need the else part, you can use this pattern:
boolean prematureEnd = true;
end: {
List<People> people = family.getPeople(); if(people == null || people.isEmpty()) break end;
People person = people.get(0); if(person == null) break end;
Address address = person.getAddress(); if(address == null) break end;
PostalCode postalCode = address.getPostalCode(); if(postalCode == null) break end;
System.out.println("Do stuff");
prematureEnd = false;
}
if(prematureEnd) {
System.out.println("The else part");
}
Certain IDEs will break this formatting, unless you instruct them not to (see this question).
Your conditionals must be inverted - you tell the code when it should break, not when it should continue.
One more thing - your code is still prone to breakage. You must use if(family.getPeople() != null && !family.getPeople().isEmpty()) as the first line in your code, otherwise an empty list will throw a NPE.
If you can use groovy for mapping it will clean up the syntax and codes looks cleaner. As Groovy co-exist with java you can leverage groovy for doing the mapping.
if(family != null) {
if(family.getPeople() != null) {
if(family.people.get(0) != null) {
if(people.get(0).getAddress() != null) {
if(people.get(0).getAddress().getPostalCode() != null) {
//FINALLY MADE IT TO DO SOMETHING!!!
}
}
}
}
}
instead you can do this
if(family?.people?[0]?.address?.postalCode) {
//do something
}
or if you need to map it to other object
somobject.zip = family?.people?[0]?.address?.postalCode
Not such a cool idea, but how about catching the exception:
try
{
PostalCode pc = people.get(0).getAddress().getPostalCode();
}
catch(NullPointerException ex)
{
System.out.println("Gotcha");
}
If it is rare you could ignore the null checks and rely on NullPointerException. "Rare" due to possible performance problem (depends, usually will fill in stack trace which can be expensive).
Other than that 1) a specific helper method that checks for null to clean up that code or 2) Make generic approach using reflection and a string like:
checkNonNull(family, "people[0].address.postalcode")
Implementation left as an exercise.
I was just looking for the same thing (my context: a bunch of automatically created JAXB classes, and somehow I have these long daisy-chains of .getFoo().getBar().... Invariably, once in a while one of the calls in the middle return null, causing NPE.
Something I started fiddling with a while back is based on reflection. I'm sure we can make this prettier and more efficient (caching the reflection, for one thing, and also defining "magic" methods such as ._all to automatically iterate on all the elements of a collection, if some method in the middle returns a collection). Not pretty, but perhaps somebody could tell us if there is already something better out there:
/**
* Using {#link java.lang.reflect.Method}, apply the given methods (in daisy-chain fashion)
* to the array of Objects x.
*
* <p>For example, imagine that you'd like to express:
*
* <pre><code>
* Fubar[] out = new Fubar[x.length];
* for (int i=0; {#code i<x.length}; i++) {
* out[i] = x[i].getFoo().getBar().getFubar();
* }
* </code></pre>
*
* Unfortunately, the correct code that checks for nulls at every level of the
* daisy-chain becomes a bit convoluted.
*
* <p>So instead, this method does it all (checks included) in one call:
* <pre><code>
* Fubar[] out = apply(new Fubar[0], x, "getFoo", "getBar", "getFubar");
* </code></pre>
*
* <p>The cost, of course, is that it uses Reflection, which is slower than
* direct calls to the methods.
* #param type the type of the expected result
* #param x the array of Objects
* #param methods the methods to apply
* #return
*/
#SuppressWarnings("unchecked")
public static <T> T[] apply(T[] type, Object[] x, String...methods) {
int n = x.length;
try {
for (String methodName : methods) {
Object[] out = new Object[n];
for (int i=0; i<n; i++) {
Object o = x[i];
if (o != null) {
Method method = o.getClass().getMethod(methodName);
Object sub = method.invoke(o);
out[i] = sub;
}
}
x = out;
}
T[] result = (T[])Array.newInstance(type.getClass().getComponentType(), n);
for (int i=0; i<n; i++) {
result[i] = (T)x[i];
}
return result;
} catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
and my favorite, the simple try/catch, to avoid nested null checks...
try {
if(order.getFulfillmentGroups().get(0).getAddress().getPostalCode() != null) {
// your code
}
} catch(NullPointerException|IndexOutOfBoundsException e) {}

Categories

Resources