If Object
where accept on the catch clause, something like this would actually work:
try {
if (needToThrow) {
List<String> messages = new ArrayList<String>();
list.add("a nice message");
list.add("another message");
list.add("random message");
throw messages;
} else {
//do other stuff here
}
} catch (List list) {
System.out.println("Got a list of messages, lets handle them");
}
Yet that would be a very strange way to control the execution flow, something that a simple if
statement would solve.
So, the try and catch mechanism is not for doing basic flow control, but handling unexpected results. When a part of the code hits an unexpected result, it throws a message indicating that he cannot continue, he will abort the next statement and return the execution to the scope above. Hes basically saying I received an error and cannot continue, someone handle this situation. For someone to deal with this situation, resources needs to be gathered: the JVM will make a snapshot of the whole stack and put it inside a Throwable
object. Thats why you can only catch something that is a Throwable
. Also the above example would perform poorly as error resources would be gathered where it is not necessary.
On the two known Throwable
types
Situations where the program can recover from are classified as Exceptions
, like trying to open a missing file, connecting to somewhere that is not reachable, trying to access a wrong URL and so on.
When the program cannot recover, those situations are classified as Errors
, like running out of memory or running into a compiling error.
Although you could still write your own class that inherits from Throwable
, the two above types already cover all the possible error types (being recoverable or being not recoverable), so you probably wont see anything being catch that are not from any of those.
Also, catching a Throwable
is a bad practice (Can you handle something that cannot be handled like Errors
?). When you want to "catch anything in my code", catch Exception