0

I am not advocating catching a NullPointerException as it is always a code smell/lazy approach. But, consider you want to access a field deep inside nested beans.

Defensive NPE check

if (  null != a && null != a.b() && null ! = a.b().c() && null !=   a.b().c().d() ) 
{
     doSomething( a.b().c().d().e );
}

Lazy NPE Check

try
{
     doSomething( a.b().c().d().e ); 
}
catch(NullPOinterException npe)
{
}

Two questions:

  1. Performance

    At what depth [a,b,c....z as in the example above] is the heavier weight try/catch more efficient than Defensive NPE check?

  2. Readability

    At what depth [a,b,c....z as in the example above] is the try/catch more readable than multiple &&?

Please don't answer 're-factor the nested beans' :-)

user207421
  • 305,947
  • 44
  • 307
  • 483
J W
  • 19
  • First code smell: `a.b().c().d().e`. Second code smell: why can things even be `null`? Finally: what do you do in the `else` / `catch` case? – luk2302 Nov 10 '17 at 09:10
  • 2
    *"Please don't answer re-factor the nested beans"* - that is **exactly** what you should do. – luk2302 Nov 10 '17 at 09:10
  • 1
    and why would you automatically assume the try/catch is more efficient? – Stultuske Nov 10 '17 at 09:10
  • Your actually question is irrelevant because the performance is completely irrelevant and both codes are not readable. – luk2302 Nov 10 '17 at 09:11
  • 1
    I think this is a perfectly valid question. Some beans can't be refactored because they come from a third party and you don't have the source code. Many SOAP and REST-based APIs return nulls instead of empty lists. It's unfortunately just the way it is. So @luk2302 the request not to re-factor the nested beans is not as silly as it sounds. – DodgyCodeException Nov 10 '17 at 09:38
  • If you could use Groovy: `doSomething( a?.b()?.c()?.d()?.e );` (assuming `doSomething` can easily handle a null). – DodgyCodeException Nov 10 '17 at 09:40
  • *Anything can be null* - that is a Java problem you can simply circumvent by not using null EVER and having every null lead to a crash immediately instead of dealing with it explicitly. – luk2302 Nov 10 '17 at 09:41
  • Possible duplicate of [if(null check)-else vs try catch(NullPointerException) which is more efficient?](https://stackoverflow.com/questions/15172367/ifnull-check-else-vs-try-catchnullpointerexception-which-is-more-efficient) – user902383 Nov 10 '17 at 09:42
  • 1
    "Not using null EVER" - that is neither practical or sensible in all but a 101 java program. Any large enterprise system/ any touch points with 3rd party you must handle the null situations. (Appreciate Optional<..> ). – J W Nov 10 '17 at 09:49
  • @Stiltuske I know( and stated in the question) the try/catch is less efficient i.e. object creation v checking if an area of memory is null. But I asked at what point they does multiple increasingly deep null checks become less efficient than a single try/catch ? :-) – J W Nov 10 '17 at 09:54
  • I think the answer wrt performance depends a lot on expected percentage of finding a null and the processor architecture (predictive branching etc) and the answer wrt readability is opinion-based. – DodgyCodeException Nov 10 '17 at 10:08
  • @DodgyCodeException i remember this one, it was actually a jcp proposal but not implemented i dont know why – HRgiger Nov 10 '17 at 10:28
  • Also there is Objects.requireNonNull and a bit more elegant solution https://stackoverflow.com/a/2386013/706695 – HRgiger Nov 10 '17 at 10:35

1 Answers1

1

Try using Optional:

Optional.ofNullable(a)
    .map(A::b)
    .map(B::c)
    .map(C::d)
    .map(d -> d.e)
    .ifPresent(()->X::doSomething);

Not sure if it's any more readable. But sometimes it looks as if Optional is a class that is looking for ways to be used.

DodgyCodeException
  • 5,963
  • 3
  • 21
  • 42