Handling Exceptions
The hierarchy
Throwable splits into Error (serious JVM problems, not normally caught) and Exception. RuntimeException and its subclasses are unchecked; every other Exception is checked and must be caught or declared with throws. Common unchecked exceptions: NullPointerException, ArithmeticException (integer divide by zero), ArrayIndexOutOfBoundsException, ClassCastException, NumberFormatException, and IllegalArgumentException.
try / catch / finally
Catch blocks are tested in order, so a superclass catch before a subclass catch makes the later one unreachable and fails compilation. Multi-catch (catch (IOException | SQLException e)) types the variable as the nearest common supertype and makes it effectively final; the alternatives may not be related by inheritance. finally runs whether or not an exception is thrown (except after System.exit), and a return inside finally silently discards earlier returns and pending exceptions. Try-with-resources closes resources in reverse declaration order and requires AutoCloseable.
Declaring and creating exceptions
throws on a method declares checked exceptions for callers. Only Throwable subtypes can be thrown. A custom exception extends Exception (checked) or RuntimeException (unchecked).
Traps
Catching a checked exception that the try block can never throw is a compile error. Overriding methods may narrow, but not widen, the checked exceptions declared by the overridden method. An unchecked exception needs no handling and compiles fine.
Worked example
int x = 5 / 0; compiles but throws ArithmeticException at runtime, so surrounding it with catch (ArithmeticException e) is valid - but catch (IOException e) there would not compile.