Exceptions vs Errors in Java
What Are Exceptions?
Exceptions are errors that occur that can be recovered from. For example, reading a file that doesn't exist will cause an exception. This doesn't mean that the application can't recover from it but instead may need special handling around when this scenario occurs.
Exception classes end with the suffix of Exception. Exceptions come in two forms, checked exceptions and unchecked exceptions. Both are exceptions, but they are used for different kinds of exceptions.
Checked Exceptions
Checked exceptions extend the Exception class and are used when you can recover from a condition. They are checked by the compiler at compile time to see if they are included in a method or constructors throws clause or if they are handled in a try block. Examples of checked exceptions are IOException and SQLException.
Unchecked Exceptions
Unchecked exceptions extend RuntimeException. Having an exception extend RuntimeException instead of Exception is what makes it an unchecked exception. Unchecked exceptions are for programming errors such as an IndexOutOfBoundsException or NullPointerException.
What Are Errors?
Error classes end with a suffix of Error and extend the Throwable class. Errors are exceptions for serious problems that cannot be reasonably recovered from. Examples of errors are OutOfMemoryError, StackOverflowError, and VirtualMachineError. Errors are considered unchecked exceptions, so they aren't checked by the compiler.
The Throwable Class
Throwable is the class that both Error and Exception extend. Generally, you should never catch Throwable because you wouldn't be able to determine if it is an error or not. One place where you might have a use case to catch Throwable would be in a Runnable (a separate thread). There could be a situation where the thread throws an error, so you'd catch Throwable in a Runnable and do something with it, such as reporting it to the user or support team. The thread will die, but the application may be able to recover.
Conclusion
When handling exceptions, you want to be as narrow as possible with what subclass you specify in a catch block. Avoid using superclasses unless it makes sense, and avoid catching Throwable and Error.