(OOP6) Exception Handling
👷‍♂️

(OOP6) Exception Handling

 
A Java exception is an object that describes an exceptional condition (an error) that occurs in a part of the code. The exception may be handled by the method itself or passed on when thrown. But in the end, the exception is caught and processed.

Exception Types

All exception classes are subclasses of a built-in class called Throwable. This has two distinct branches - Exception and Error. The Exception branch further classifies known issues, such as division by zero or invalid array indexing (under RuntimeException).
(The Error subclass defines all conditions that aren’t expected to be caught under normal circumstances by the program.)
notion image

Uncaught Exceptions

class Test { public static void main(String[] args) { int d = 0; int a = 42 / d; } } // the exception stack trace will include the class // name, the method name, and the line number.
java.lang.ArithmeticException: / by zero at Test.main(Test.java:4)

Custom Exception Subclasses

Creating custom exceptions can be done by subclassing the Exception class, which in turn is a subclass of the Throwable that has its own overridable methods.
class MyException extends Exception { private int detail; MyException(int a) { detail = a; } // method override. public String toString() { return "MyException[" + detail + "]"; } }

Using ‘try’ & ‘catch’

class Test { public static void main(String[] args) { try { int d = 0; int a = 42 / d; System.out.println("This will not be printed."); } catch (ArithmeticException e) { System.out.println("Division by zero."); } System.out.println("After catch statement."); } }
Division by zero. After catch statement.

Multiple ‘catch’ Clauses

class Test { public static void main(String[] args) { try { int a = args.length; System.out.println("a: " + a); int b = 42 / a; int c[] = { 1 }; c[42] = 99; } catch (ArithmeticException e) { System.out.println("Division by 0: " + e); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Array index OOB: " + e); } System.out.println("After try/catch blocks."); } }
Divide by 0: java.lang.ArithmeticException: / by zero After try/catch blocks. a = 1 Array index oob: java.lang.ArrayIndexOutOfBoundsException: Index 42 out of bounds for length 1 After try/catch blocks.

Nested ‘try’ Statements

class Test { public static void main(String[] args) { try { int a = args.length; int b = 42 / a; System.out.println("a: " + a); try { if (a == 1) a = a / (a - a); if (a == 2) { int c[] = { 1 }; c[42] = 99; } } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Array index OOB: " + e); } } catch (ArithmeticException e) { System.out.println("Division by 0: " + e); } } }

Other Exception Keywords

class KeywordsDemo { // throw: throw a ThrowableInstance. static void demoThrow() { try { throw new NullPointerException("demo"); } catch (NullPointerException e) { System.out.println("Caught inside 'demoThrow()'."); } } // throws: if a method causes an exception it does not // handle, it must specify this behaviour for its callers. static void demoThrows() throws IllegalAccessException { System.out.println("Inside 'demoThrows()'."); throw new IllegalAccessException("demo"); } // finally: a block of code executed after the try/catch // block is complete. static void demoFinally() { try { System.out.println("Have something here."); throw new RuntimeException(); } catch (RuntimeException e) { System.out.println("Here's the catch."); } finally { System.out.println("This will run at the end."); } } }

Java’s Built-in Exceptions

Unchecked exceptions are those that do not require a throws specification in the method. They are subclasses of RuntimeException.
notion image
Checked exceptions are the exceptions from java.lang that must be specified under throws if not handled by the method itself.
notion image

Chained Exceptions

These were introduced in Java in JDK 1.4 (yes, that old), and allow you to associate exceptions with each other. This helps the second exception describe the cause of the first exception. Two constructors were introduced for this feature.
// also been added to Error, Exception and RuntimeException Throwable(Throwable causeExc) Throwable(String msg, Throwable causeExc)
There’s also getCause() to get the underlying exception, and initCause() which associates a new causeExc with the above layer.

Additional Exception Features

From JDK 7, a couple of new features were introduced.
  1. Multi-catch: It allows two or more exceptions to be caught by the same clause, as catch (ExceptionOne | ExceptionTwo e) { ... }. Each multi-catch parameter is implicitly ‘final’.
  1. Precise rethrowing: This feature restricts the type of exceptions that can be rethrown to only those checked exceptions that the associated ‘try’ block throws, that are not associated with preceding ‘catch’ blocks.