Exceptions should be just that.. exceptions. Best practice when using exceptions is to use them to cover the situation in which something contrary to what you would expect to happen happens. The classic example is the FileNotFoundException which gets thrown when a file simply isn't there. If you're testing the existence of the file, then you use File.exists() since you're simply prodding with a 10 foot stick to see if you hit something.
You could technically accomplish the same results by surrounding it in a try catch and using the file as if it existed, but A) exceptions are generally costly resource-wise and B) programmers are going to assume you meant the file to exist if it was in a try catch, which adds to the overall confusion of a program.
There are many situations in which I'll write a method which fetches some value from a database. A thousand things could go wrong, and seeing how I only need one small piece of information, it's inconvenient to surround the call with a try catch list that contains 5 various exceptions. So, I'll catch exceptions in the fetch method. If something goes wrong, I take whatever appropriate action to close the database connection or whatnot in the finally clause and return null. This is good practice not only because it simplifies your code but also because "null" sends the same message you could have gotten from an exception.. that something didn't go as planned. Manage exception specifics in the fetch method, but manage what to do when things don't go as planned in the receiving end by checking to see if the result was null.
For example:
Integer getUserCount() {
Integer result = null;
try {
// Attempt to open database and retrieve data
} catch (TimeoutException e) {
logger.error("Got a watch?");
} catch (MissingDatabaseException e) {
logger.error("What are you smoking?");
} catch (PermissionsToReadException e) {
logger.error("Did you *really* think you were getting away with that?");
} catch (PressedSendButtonToHardException e) {
logger.error("Seriously.. just back away from the computer... slowly..");
} catch (WTFException e) {
logger.error("You're on your own with this one.. I don't even know what happened..");
} finally {
// Close connections and whatnot
}
return result;
}
void doStuff() {
Integer result = getUserCount();
if(result != null) {
// Went as planned..
}
}