Just because an exception is created, doesn't mean it's thrown
public static void main(String[] args) { new Exception(); System.out.println("Yippee!!"); // prints "Yippee!!" }
Just because there's a catch clause, doesn't mean something was caught
public static void main(String[] args) throws Exception { try { System.out.println("No math for me!"); } catch (ArithmeticException e) { System.out.println("Math was wronged!"); } // prints "No math for me!" }
Exception can be thrown during the creation of another exception
public static void main(String[] args) { try { throw new NullPointerException(args[-1]); } catch (NullPointerException e) { System.out.println("Ooops!"); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Ooh lala!!"); } // prints "Ooh lala!!" }
You can only catch things thrown from where your try is
public static void main(String[] args) throws Exception { try { args[-1] = null; } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Gotcha!"); args[1/0] = null; } catch (ArithmeticException e) { System.out.println("You missed me!"); } // prints "Gotcha!" } // Exception in thread "main" java.lang.ArithmeticException: / by zero
Practically under "all" circumstances, finally is always executed
public static void main(String[] args) { try { throw new Exception(); } catch (Exception e) { System.out.println("Oops!"); args[-1] = null; } finally { System.out.println("Yay!"); } // prints "Oops!", "Yay!", } // Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
Abrupt completion of finally trumps abrupt completion of try/catch
static String greetings() { try { return "No mood!"; } finally { return "Hey buddy!"; } } public static void main(String[] args) throws Exception { System.out.println(greetings()); // prints "Hey buddy!" try { args[-1] = null; } catch (ArrayIndexOutOfBoundsException e) { throw new Exception("Catch me if you can!"); } finally { throw new Exception("Yoink!"); } } // Exception in thread "main" java.lang.Exception: Yoink!