I was reading some things about exception handling in Java, to be able to write better code. OK, I admit, I am guilty; I\'ve used too much try-catch{} blocks, I\'ve used
Many good answers, let me just add a couple of points that haven't been mentioned.
For many, probably most, of the exceptions that I create, the only thing the program can realistically do is display an error message and give the user the opportunity to change his inputs and try again. Most validation errors -- invalid date format, non-digits in a numeric field, etc --fall into this category. For these I create a single exception type, which I usually call "BadInputException" or "ValidationException", and I use that same exception class throughout the system. When there's an error, I 'throw new BadInputException("Amount must contain only digits")' or some such, and then have the caller display it and let the user retry.
On the other hand, if the caller is reasonably likely to do different things in different cases, make them different exceptions.
Easy rule of thumb: If you have two or more exceptions that are ALWAYS handled with identical, duplicate code, combine them into a single exception. If your catch block is doing additional checking to figure out what kind of error this really is, it should have been two (or more) exception classes. I've seen code that does exception.getMessage and then looks for keywords in the message to figure out what the problem was. This is ugly. Make multiple exceptions and do it cleanly.
(a) It avoids the problem of "magic" return values, like non-null string is a real answer but null means there was an error. Or worse, "NF" means file not found, "NV" means invalid format, and anything else is the real answer. With exceptions, an exception is an exception and a return value is a return value.
(b) Exceptions neatly skip the main line of code. Usually when there's an error you want to skip a whole bunch of processing that does not make sense without valid data, and go right to displaying an error message and quitting, or retrying the operation, or whatever is appropriate. In the bad old dies we would write "GOTO panic-abort". GOTOs are dangerous for all the reasons that have been much discussed. Exceptions eliminate what was perhaps the last remaining good reason to use a GOTO.
(c) Perhaps a corrollary to (b), you can handle the problem at the appropriate level. Sometimes when an error happens you want to retry the exact same function -- like an I/O error might represent a transient communications glitch. At the other extreme, you could be ten levels deep in subroutines when you get an error that cannot be handled in any way but bombing out of the entire program and displaying a "sorry, armageddon has occurred, everybody in here is dead" message. With exceptions it's not only easy to choose the correct level, but you can make different choices in different modules.