1

Can someone help me provide a generic optimized code to test for null objects? What I am basically looking for is a method, that can take any object as input and maybe the path and return a boolean specifying if the target object is null or not.

Something like this:

public boolean isNull(Object Obj, String Path){
    // ... 
}

Path being something like: A.getB().getC(). . .

so A is passed as object, and the isNull method first calls getB() checks if the returned object is not null then calls getC() and so forth.

MWiesner
  • 8,868
  • 11
  • 36
  • 70
M Ah
  • 11
  • 1
  • 2
  • 1
    Since you'd have to parse the path and then use reflection to achieve this fairly simple goal, any solution is going to be anything but "optimized". Normally you wouldn't need such a thing anyway, as class invariants should be maintained by the respective classes. – biziclop Nov 25 '15 at 16:37
  • 4
    The question has a straight answer and is: use reflection. But I think the problem is about you trying to do defensive programming for lots of fields of your classes, which leads to an odd design. – Luiggi Mendoza Nov 25 '15 at 16:37
  • 4
    You're going to be looking for a while then. Instead of wasting your time on this, I recommend you learn how to program defensively and use what the language gives you as tools (such as `Optional` for nullable references). – Kayaman Nov 25 '15 at 16:38
  • Switch to a language that supports this case. Try http://docs.groovy-lang.org/next/html/documentation/core-operators.html#_safe_navigation_operator – Jayan Nov 25 '15 at 16:39
  • 1
    @Jayan or use [`Optional`](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html) and keep using Java. Still, the problem behind the scenes worries me more than providing a specific solution for this. – Luiggi Mendoza Nov 25 '15 at 16:40
  • The objective while you develop a program, is not to avoid exceptions, but handle them in the right form. Yes, you can use reflection to do that, but what about the other exceptions generated by the program, i.e. a divide by zero or something like that. – gersonZaragocin Nov 25 '15 at 16:42
  • @gersonZaragocin It is perfectly good practice to check your input for validity before you use it, and that includes checking that things aren't `null`, and throwing a more specific exception of the failed precondition rather than relying on something further down the line throwing an NPE. But if you have to do this several levels deep, there's likely to be something wrong with your design. – biziclop Nov 25 '15 at 16:45
  • @biziclop 100% agree with that. What I am trying to show him is that if that design persists, other kind of Exceptions generated by the program could have the same type of implementation and it would never be desirable. – gersonZaragocin Nov 25 '15 at 16:52
  • 1
    "that can take any object as input _and maybe the path_" -> which path ? Is `A` the same as the `Obj` parameter (_please_ use lowercase for those)? – Mr_and_Mrs_D Nov 25 '15 at 17:02
  • It sounds like you're looking for a [null coalescing operator](https://en.wikipedia.org/wiki/Null_coalescing_operator), which [does not exist in Java](http://stackoverflow.com/questions/5223044/is-there-a-java-equivalent-to-null-coalescing-operator-in-c). It was [proposed for inclusion in Java 7](https://blogs.oracle.com/darcy/entry/project_coin_final_five) but rejected. – dimo414 Nov 25 '15 at 17:53
  • Guy Thanks a lot, help is much appreciated. Am trying to get around the PMD cyclomatic complexity limitation. at the moment in the current rule set, its set to about 10, that gives very little room to add other logic to the method incase an object needs to be assertedNotNull before using it. Hence the need for this. Also its a large scale application that uses object composition to multiple levels at times. Again am new to coding, hope am making sense – M Ah Nov 30 '15 at 12:16
  • Love the idea ... use in java streams `Stream.of(arr).filter(Object::isNotNull).forEach(...);` seems to be a good use case for it, unfortunately, it is not there. But this form is not unfathomable: `Stream.of(arr).filter(r->r != null).forEach(...);`, just that each use will result in potentially a new method reference. – YoYo May 11 '18 at 18:08

3 Answers3

3

There's plenty in the comments highlighting techniques that can be used to avoid null checks.

If you really need to write something to do null checking generically, you could build a small object graph that uses Functions to walk the graph being checked, something like this:

public class NullCheck<T>
{
  private T root;

  public NullCheck(T root)
  {
    this.root = root;
  }

  public <C> NullCheck<C> with(Function<T, C> getter)
  {
    return root != null ? new NullCheck<>(getter.apply(root)) : new NullCheck<>(null);
  }

  public boolean isNull()
  {
    return root == null;
  }

  public boolean isNotNull()
  {
    return root != null;
  }
}

Which given a Person that has an Address that has an attribute zipCode, you can the use the NullCheck to write code like this:

if (new NullCheck<>(person).with(Person::getAddress).with(Address::getZipCode).isNotNull())
{
  ...
}
Nick Holt
  • 33,455
  • 4
  • 52
  • 58
2

There are some strategies available there to test for null objects.

You can use Guava libraries to check if a reference is null or not using the Preconditions API.

Check the documentation for the not null check: http://google.github.io/guava/releases/snapshot/api/docs/com/google/common/base/Preconditions.html#checkNotNull(T)

There is an interesting article on the Guava Github page explaining how to avoid null.

If you're using Java 8, you can use the Optional type to avoid testing for null references all the time.

Rafael Naufal
  • 411
  • 3
  • 6
0

When you are preparig your object, you can put @NotNull annotation to the param you have, so when you are getting it out, you will have something else than null (if you are using Java EE 6 and above). This approach can be pretty fast for doing something with the object you are getting... When you are passing null as an input, you will get an exception, to handle the exception take much more resource and time than just simply null check.

If you want to write your own approach and not use the stuff mentioned above, you can use something like this (if the exception is not needed, you can leave this out):

private static final String NE_MESSAGE = "Object is null...";
private static final String NULL_LOG = "Value is null, param name: ";

public static boolean isNull(Strin name, Object... object) {
  for(Object o : object) {
      if ( o == null) {
          NullException ne = new NullException(NULL_MESSAGE);
          LOGGER.error(NULL_LOG + name);
          throw ne;
       }
     }
   return Boolean.FALSE;
}
Franky
  • 11
  • 4