Uncaught exceptions are for external problem management, caught exceptions for internal
In general, caught exceptions (in your try-catch-finally
block) are for problems that your application can do something about. Uncaught, or runtime, exceptions are for problems that are outside the scope of your application to fix by itself (null pointer, database connection failure and so on). Typically a runtime exception is indicating a weakness in your system that an admin or a developer has to address.
When to choose a uncaught exception
Choose a runtime exception when you know that no-one further up the call stack is going to be able to recover without a retry.
"The database connection is borked.
This application is not going to be
able to restart it since it'll have
been provided by JNDI. This
application should stop attempting
database access right now."
When to choose a caught exception
Choose a caught exception when you know that recovery is possible with a bit of data manipulation from the caller.
"Hey, I got a ParseException, guess
I'll add in the time field since it
was missing. Should've checked that
beforehand..."
Overall, try to stick with the well-defined exceptions already in the language (less code to share around and explain). Understand why they are caught or uncaught. If you absolutely must create your own exception then try to keep the number of variations down and make it helpful in reporting exactly what went wrong. Consider backup up your exception with a detailed log entry if you can.