1

In my code I have something like this

// 1st method
if (a == null) {
    return false;
}
if (a.getB() == null {
    return false;
}
if (a.getB().getC() == null {
    reutrn false;
}
return a.getB.getC().isFoo();

Which is clear but very wordy. Meanwhile, something like this is less wordy but maybe not as clear because it's using a try-catch in a nontraditional manner.

// 2nd method
try {
    return a.getB().getC().isFoo();
} catch(NullPointerException e) {
    return false;
}

Is there any reason to specifically not use the 2nd method, is it a bad practice? As an aside, is there any reason one should be used or is preferred over the other?

Captain Man
  • 6,997
  • 6
  • 48
  • 74
  • 5
    In general, you shouldn't use exceptions for flow control control (it's a known anti-pattern). Read more here: http://programmers.stackexchange.com/questions/189222/are-exceptions-as-control-flow-considered-a-serious-antipattern-if-so-why – Kon Jan 14 '15 at 20:15
  • 4
    They are not even semantically equivalent: the second version would quietly mask any NPEs that `getB()`, `getC()` and `isFoo()` might throw. That could lead to some fun debugging sessions. – NPE Jan 14 '15 at 20:16
  • @NPE This is a good point, perhaps I should have put the assumption in the question that this wouldn't happen (although in practice this is not a good assumption) – Captain Man Jan 14 '15 at 20:20
  • 1
    @CaptainMan: As you point out, that's not a good assumption, mainly because it forces a contract upon `getB()`, `getC()`, `isFoo()` *as well as any other functions those three might call*. – NPE Jan 14 '15 at 20:22
  • 1
    My preference would be to put all the `if` conditions on one line like `if (a == null || a.getB() == null || a.getB().getC() == null ) {`. – Dawood ibn Kareem Jan 14 '15 at 20:22
  • Java 8 style: `return Optional.ofNullable(a).map(TypeOfA::getB).map(TypeOfB::getC).map(TypeOfC::isFoo).orElse(false);` – Holger Jan 14 '15 at 20:29
  • @Holger Much as I like some of the new goodies in Java 8, I feel that is WAY less readable than either of the OP's original choices, or my alternative. – Dawood ibn Kareem Jan 14 '15 at 20:35
  • @ David Wallace: You can also use `return Optional.ofNullable(a).map(x->x.getB()).map(x->x.getC()).map(x->x.isFoo())‌​.orElse(false);` and, of course, format it better in your source code than I can in the comments. – Holger Jan 14 '15 at 20:38
  • Why is the 2nd method considered flow control? The goal is to see if foo is true or not, so in the exceptional case that a, b, or c doesn't exist we catch it and return false. Would your answer differ if it were `return a.b.c.foo;`? I agree that exceptions shouldn't be used for flow control, I am just having trouble understanding why this is an example of flow control. – Captain Man Jan 14 '15 at 21:23

0 Answers0