try/catch vs null check in java

Sometimes I face I must write a piece of code like this (usually it have more nested if and more complex structure but for the example is enought)

public void printIt(Object1 a){
  if (a!=null){
     SubObject b= a.getB();
     if (b!=null){
         SubObject2 c=b.getC();
         if(c!=null){
             c.print();
         }
     }
  }
}

when I dont need to know what failed and if something is null do nothing, an approach could be

public void printIt(Object1 a){
    try{
      a.getB().getC().print();
    }catch (NullPointerException e) {
    }
}

Is there something wrong in this second form like performance or other kind of issues?


The exception version (similar to chains using Groovy's safe-navigation operator ?.) makes it really easy to take the Law of Demeter (or as I call it, Demeter's Strongly-Worded Suggestion) and make it your plaything for the night.

Similarly, deeply-nested if-statements leads to difficult-to-read code, and underneath it all, the same "violation" exists, and the cyclomatic complexity of such methods is high.

public void printIt(Object1 a) {
    if (null == a) {
        return;
    }

    SubObject b = a.getB();
    if (null == b) {
        return;
    }

    SubObject2 c = b.getC();
    if (null == c) {
        return;
    }

    c.print();
}

I'd rather see LAMs (Little Auxiliary Methods) in appropriate places that encapsulate the checks and pretty much eliminate the need for the question altogether.


Yes. The second version will have terrible performance.

Don't use exceptions for normal control flow. Effective Java item 57: use exceptions only for exceptional situations.

==UPDATE==

Even ignoring performance issues (exceptions are faster than they once were, according to my benchmark, but not nearly as fast as a simple if check), it's really code-smelly to use exceptions for standard program flow like this. JVM bytecode has special optimizations it can do for null checks, even in if statements. The first code sample is vastly preferred.