Java: Return Values vs Exceptions
You should only use exceptions for exceptional situations. An exceptional situation is an unexpected situation that is out of the ordinary. A situation is not exceptional just because it's less common than other situations. In a non-exceptional situation you should use return values instead of exceptions.
| Exceptional Examples | Non-exceptional Examples | 
                
  | 
              
                
  | 
            
Exceptional control flow is more complicated than ordinary if statements. In other words, by chosing exceptions for non-exceptional control flow you're making the code more complicated than it needs to be.
try {
    foo();
    // then...
} catch (FooException ex) {
    // else...
}
          foo() return true on success:
            if (foo()) {
    // then...
} else {
    // else...
}
 
          Or, if the return value of foo() is reserved for normal operation:
Example: Instead of this…
try {
    value = foo();
    // then...
} catch (FooException ex) {
    // else...
}
        foo() return FooResult…
            FooResult result = foo();
if (result.success()) {
    value = result.getValue();
    // then...
} else {
    // else...
}
          if (isFooAvailable()) {
    value = foo();
    // then...
} else {
    // else...
}
 
          In the last two snippets, it's perfectly fine to let result.getValue() / foo() to throw an unchecked exception if result.success() / isFooAvailable() returns false.
If all you want to do is to skip the remaining part of a sequence of statements:
Example: Instead of this…
try {
    if (!initFoo()) throw AbortInit();
    // ...
    if (!initBar()) throw AbortInit();
    // ...
} catch (AbortInit e) {
}
        void init() {
    if (!initFoo()) return;
    // ...
    if (!initBar()) return;
    // ...
}
          break:
            init: {
    if (!initFoo()) break init;
    // ...
    if (!initBar()) break init;
    // ...
}