In theory, the Java exception hierarchy makes some sense:
Throwable* -> Error (OutOfMemoryError, etc.) -> Exception (IOException, SQLException, etc.) -> RuntimeException (IndexOutOfBoundsException, NullPointer, etc.)
At present, the theory underlying this does have some meaning. (Actual implementation leaves much to be desired due to congestion, sad.)
Error -descended Throwable objects are serious errors due to which it is expected that the program will not be able to recover. (As a rule, you do not understand this, in other words.) One of these statements is a serious general systemic problem. For example, when you run out of memory, this is a serious setback somewhere, because in theory the GC was already desperate to make room for you. Catching this is pointless.
Exception -descended Throwable objects are all errors that can reasonably be expected during a normal operation; such as network errors, file system errors, etc. Indeed, with the exception of those that came from RuntimeException , it is required that programs explicitly handle these errors - these are the so-called "checked exceptions". (Of course, bad programmers will "cope" with them by deleting them, but this is a programmer’s problem, not a system problem.)
RuntimeException -descended Throwable objects are slightly different. These are errors that should not be expected, but which the program could reasonably recover after they occur. Therefore, they are not checked (programs are not required to process them), but they can be, if there are reasonable ways to cope with the situation. In the general case, these exceptions are some kind of software error (unlike the previous category, which are expected errors that occur during normal operation).
So, does this hierarchy make sense? Well, at some level it seems. Error thrown by the system and is a serious error, which is probably going to kill your program. RuntimeException used properly, a RuntimeException is thrown by system libraries (or occasionally by your own program) and usually means that someone is screwed somewhere, but this is normal because you can recover it. Other Exception objects are expected errors, which are actually part of the specified interface of your objects.
But...
This last item is a problem. Verified exceptions are, quite frankly, a serious pain in the lower body anatomy. They uselessly clutter up the code with the exception handling template in such a way that, in my opinion, render (and many others, I could add!), The whole point of exceptions: the separation of error detection and error handling. Forcing each method in the chain to handle the & mdash exception, even if it just overwrites it and passes it! - the code clutters the little things of error handling to such an extent that it is slightly better than returning status codes and processing them after each method call.
If Java were a smarter programming language, checked exceptions would be checked at compile time / reference to see if they are handled correctly at the system scale, and not when each method is called in every class file. Unfortunately, the whole Java architecture does not allow this level of analysis of the entire program, and the result, again, in my opinion (but again shared by many), is actually a mixture of the worst two worlds handling exceptions and returning errors: you get most of the boilerplate forests with obvious errors, but you also get COME FROM exception behavior.