C2: Advanced Exception Handling

CPSC 210

Learning Goals

  • To design appropriate exception hierarchies to provide flexibility in handling exceptions
  • To identify and declare exceptions as checked or unchecked
  • To understand what it means to throw unchecked exceptions

Throwing Multiple Exceptions

/*
 * REQUIRES: accountName has a non-zero length, initialBalance >= 0
 * //...
 */
public Account(String accountName, double initialBalance) {








}

AND

  throws IllegalNameException, IllegalBalanceException {
  • If we have different things that can go wrong, we should have different types of exceptions
  • We can then address them individually in the caller...
if (name == null || name.isEmpty()) {
  throw new IllegalNameException();
}
if (initialBalance < 0) {
  throw new IllegalBalanceException();
}
// ...

Throwing Multiple Exceptions (2)

private void init() {
  try {
    cheq = new Account("Joe", 145.00);
    sav = new Account("Joe", 256.50);
  } catch (IllegalBalanceException e) {
    System.err.println("Illegal balance given to one of the accounts");
  } catch (IllegalNameException e) {
    System.err.println("Illegal name given to one of the accounts");
  }
}

What should we put within one try block?

private void init() {
  try {
    cheq = new Account("Joe", 145.00);
  } catch (IllegalBalanceException e) {
    System.err.println("An illegal balance was given to CHECKING account");
  } catch (IllegalNameException e) {
    System.err.println("An illegal name was given to CHECKING account");
  }
  try {
    sav = new Account("Joe", 256.50);
  } catch (IllegalBalanceException e) {
    System.err.println("An illegal balance was given to SAVINGS account");
  } catch (IllegalNameException e) {
    System.err.println("An illegal name was given to SAVINGS account");
  }
}

It depends. Sometimes we want to differentiate.

Catching both exceptions!

Exception Hierarchies

private void init() {
  try {
    cheq = new Account("Joe", 145.00);
    sav = new Account("Joe", 256.50);
  } catch (Exception e) {
    System.err.println("Something went wrong...");
  }
}

What if we don't care about the type of exception?

Both our exceptions extend the Exception class!

  • But Exception can really be ANYTHING. How about any exception related to creation of accounts?
public class AccountCreationException 
	extends Exception {}
public class IllegalBalanceException 
	extends AccountCreationException {}
public class IllegalNameException 
	extends AccountCreationException {}
AccountCreationException e

Exception Hierarchies (2)

Throwable

Object

Error

Exception

RuntimeException

...

...

Unchecked Exceptions

Checked Exceptions

Rethrowing Exceptions

private void init() throws CouldNotStartException {
  try {
    cheq = new Account("Joe", 145.00);
    sav = new Account("Joe", 256.50);
  } catch (AccountCreationException e) {
    System.err.println("Something went wrong during account creation");
    throw new CouldNotStartException();
  }
}
  • Let's say we don't want to start our program at all if something went wrong during account creation
public static void main(String[] args) {
  try {
    new TellerApp();
  } catch (CouldNotStartException e) {
    System.err.println("Could not start the app");
  }
}

Lecture Ticket Review

Unchecked Exceptions

  • Maybe we don't want the compiler to check for some exceptions?
public class CouldNotStartException 
	extends RuntimeException {}

Note: unchecked exceptions in many cases indicate bad programming. We often don't want to explicitly throw/catch these!

private void init() throws CouldNotStartException {
  try {
    cheq = new Account("Joe", 145.00);
    sav = new Account("Joe", 256.50);
  } catch (AccountCreationException e) {
    System.err.println("Something went wrong during account creation");
    throw new CouldNotStartException();
  }
}
public static void main(String[] args) {
  try {
    new TellerApp();
  } catch (CouldNotStartException e) {
    System.err.println("Could not create accounts exception");
  }
}

Catching is optional!

Invariants / Assert Statements

  • A class invariant is a property that is always true about every instance of that class
  • For example, an invariant for our Account class would be
  • Invariants can be checked using Java assert statements
    •  
  • ​These are part of the Java language and not of jUnit!
  • Assert statements are ignored if program is not run with              flag
-ea
balance >= 0
assert(balance >= 0);

Quick Real-World Demo...

Lecture Lab

C2: Advanced Exception Handling

The End - Thank You!

Made with Slides.com