Exceptions are useful to programmatically handle both foreseen, and (somewhat) unforeseen errors.

1
2
3
4
5
6
7
try {
  doSomething()
} catch (ExceptionThing err) {
  System.out.println("Nope!");
} finally {
  System.out.println("Anyways...");
}

Throwing Exceptions

throw new SomeExceptionClass(...)

Everything is an Exception

That is, Exception is the base class of all exceptions.

We could technically catch every single possible exception with ... } catch (Exception e) { ... }

1
2
3
4
5
try {
  doSomething();
} catch (Exception e) {
  // pass
}

Note: This is discouraged, as you lose scope of which exception was raised.

Defining Custom Exceptions

To define a custom Java exception, we need to extend the abstract Exception class

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public class MyException extends Exception {
    private String message;

    public MyException(String message) {
      this.message = message;
    }

    public String getMessage() {
      return this.message
    }
}

We can then throw, and catch this exception.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
void doThing() {
  throw new MyException("Uh oh!");
}

void doOtherThing() {
  try {
    doOtherThing();
  } catch (MyException e) {
    System.out.println(e.getMessage());
  }
}

Delegating raised exceptions to other code

Consider the function

1
2
3
void tryDoIt() {
  OpenFile("test.txt");
}

If OpenFile has the possibility to throw an exception (i.e. FileNotFoundException), then we will have to acknowledge that possibility in our code

1
2
3
4
5
6
7
void tryDoIt() {
  try {
    OpenFile("test.txt");
  } catch (FileNotFoundException e) {
    System.out.println("File not found!!!");
  }
}

If we wanted to catch the exception outside of our tryDoIt function, we would have to reraise the exception.

1
2
3
4
5
6
7
void tryDoIt() {
  try {
    OpenFile("test.txt");
  } catch (FileNotFoundException e) {
    throw e;
  }
}

However in Java, we can add a hint to the method definition that it may throw the FileNotFoundException

1
2
3
void tryDoIt() throws FileNotFoundException {
  OpenFile("test.txt");
}

By using the throws keyword, we can delegate the handling of the exception to another function.

Exceptions and Inheritance

Inherited classes must not throw more exceptions than those defined by their parent - only subsets.