5

I have an object and i want to check if this object or nested fields are null. I want to print this neted field, but i should check if there is null in some level, otherwise i will get null pointer exception .

I know i can do this:

if( object != null && object.A != null && object.A.B != null && object.A.B.C != null && object.A.B.C.D != null) { doSomething( object.A.B.C.D);}

but its so long. Do you know better way to check it ?

Karthikeyan KR
  • 1,134
  • 1
  • 17
  • 38
user2751391
  • 249
  • 4
  • 14
  • 1
    You could try inserting nested fields into an array and then running a null-check for every object in the array, but I think it's too complicated to actually consider doing. But it's a possibility. – ForInfinity Mar 17 '17 at 11:52
  • Prevent them from being null. Use the NullObject pattern / paradigm. https://en.wikipedia.org/wiki/Null_Object_pattern#Java or what Axel sais vvv – Fildor Mar 17 '17 at 12:05
  • Well, if this is a complex nested data, what about doing a check at the end of this and catching the NPE, if an exception occurs, it is not valid. Using an exception is not a good idea but in some "exception", I would guess this is the easier – AxelH Mar 17 '17 at 12:05
  • You could switch to [Groovy](http://groovy-lang.org) and do `if (object?.A?.B?.C?.D) { doSomething( object.A.B.C.D);}` – Klitos Kyriacou Mar 17 '17 at 12:09
  • After all, having to go down 4 indirections is a code smell ... – Fildor Mar 17 '17 at 12:14

3 Answers3

15

Optional is a good way in Java 8.

String value = foo.getBar().getBaz().toString();

With optional it will be:

String value = Optional.ofNullable(foo)
                       .map(Foo::getBar)
                       .map(Bar::getBaz)
                       .map(Baz::toString)
                       .orElse("EmptyString");
user2751391
  • 249
  • 4
  • 14
1

You could implement an interface on all objects with method that returns all child objects and create a method that calls itself recursively to verify that all objects are set.

semywow
  • 66
  • 2
0

Let assume that this is a check to prevent misuse of a method, so this should not occurs too many time.

Simply catch this exception, this will invalidate the value.

private boolean isValid(YourObject object){
    try{
         return object.A.B.C.D != null;
    } catch (NullPointerException npe){
        return false;
    }
}

Of course, don't use this solution if you are doing a lot of validation and those return false to often, exception are an heavy process.

EDIT :

As Fildor point it out, there is a cost to use a try-catch even without exception. But using this answer I can assume this will be limited and there is not much optimization to do on this unique line.

Community
  • 1
  • 1
AxelH
  • 14,325
  • 2
  • 25
  • 55
  • But the exception is not only expensive when it occurs. The existence of try/catch alone triggers costs already. – Fildor Mar 17 '17 at 12:13
  • Mmmmh, that could change a lot then @Fildor. Is it that expensive ? See the edit and the link, this should be acceptable if this idea is really needed. – AxelH Mar 17 '17 at 12:14
  • Not *that* much. I just wanted to point it out. So if this validation is done *very* often, it could be more efficient to find a solution that does not need it. But I agree that this would have to be taken into account if and when it becomes a problem. – Fildor Mar 17 '17 at 12:21
  • @Fildor Thank you to point that out. It is good to know. I agree that this is not the best solution but this had to be said ;) – AxelH Mar 17 '17 at 12:25