View on GitHub

Notes

reference notes

Exceptions and Assertions

Definition

An exception represents an error condition that can occur during the normal course of program execution. When an exception occurs, or is thrown, the normal sequence of flow is terminated. The exception-handling routine is then executed; we say the thrown exception is caught.

Not Catching Exceptions

Scanner scanner = new Scanner(System.in);

System.out.println("Enter integer:");

int number = scanner.nextInt();

Error message for invalid input:

/* Exception in thread "main" java.lang.InputMismatchException
   at java.util.Scanner.throwFor(Scanner.java:819)
   at java.util.Scanner.next(Scanner.java:1431)
   at java.util.Scanner.nextInt(Scanner.java:2040)
   at java.util.Scanner.nextInt(Scanner.java:2000)
   at Ch8Sample1.main(Ch8Sample1.java:35)
   Error message for invalid input */

Catching an Exception

System.out.print(prompt);

try {
    age = scanner.nextInt();
} catch (InputMismatchException e){
    System.out.println("Invalid Entry. " + "Please enter digits only");
}
// AgeInputVer2.java

Lets modify the getAge method in AgeInputVer1 so that it will loop until a valid input is entered (int value).

Output:
How old are you? 12a
Invalid Entry. Please enter digits only.
How old are you? 12
Already had your birthday this year? (Y or N)Y
You are born in 2008

Getting Information

There are two methods we can call to get information about the thrown exception:

try {
    // ...
} catch (InputMismatchException e){
    scanner.next(); // remove the leftover garbage char
    System.out.println(e.getMessage());
    e.printStackTrace();
}

Quick Check

What will be displayed on the console window when the following code is executed, and the user enters abc123 and 14?

Scanner scanner = new Scanner(System.in);

try {
    int num1 = scanner.nextInt();
    System.out.println("Input 1 accepted");
    int num2 = scanner.nextInt();
    System.out.println("Input 2 accepted");
} catch (InputMismatchException e) {
    System.out.println("Invalid Entry");
}

If the user enters abc123 and 14 as input, the code will catch the InputMismatchException for the first input attempt (abc123). The catch block will be executed, and “Invalid Entry” will be displayed on the console. The program will not proceed to the second input.

So, the expected output on the console will be:

Invalid Entry

Multiple catch Blocks

A single try-catch statement can include multiple catch blocks, one for each type of exception.

while (true) {
    System.out.print(prompt);
    try {
        age = scanner.nextInt();
        if (age < 0) {
            throw new Exception("Negative age is invalid");
        }
        return age; // input okay so return the value & exit
    } catch (InputMismatchException e) {
        scanner.next();
        System.out.println("Input is invalid.\n" + "Please enter digits only");
    } catch (Exception e) {
        System.out.println("Error: " + e.getMessage());
    }
}

Exception Types

All types of thrown errors are instances of the Throwable class or its subclasses. Serious errors are represented by instances of the Error class or its subclasses, while exceptional cases that common applications should handle are represented by instances of the Exception class or its subclasses.

Throwable Hierarchy

There are over 60 classes in the Throwable hierarchy.

import java.util.InputMismatchException;
import java.util.Scanner;

public class BasicExceptionHandling {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        try {
            int num = scanner.nextInt();

            if (num != 0) {
                throw new Exception("Not zero");
            }

            System.out.println("I'm happy with the input.");
        } catch (InputMismatchException e) {
            System.out.println("Invalid Entry");
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }
    }
}

Output Analysis:

Multiple Catch Blocks

try {
    // ...
} catch (Exception e) {
    // ...
} catch (InputMismatchException e) {
    // ...
}

Importance of Order

If catch blocks are reversed, the second catch block will never be executed because any exception object that is an instance of Exception or its subclasses will match the first catch block.

The Finally Block

Purpose

In situations where certain actions must be taken regardless of whether an exception is thrown or not, use the finally block.

Example

try {
    // ...
} catch (InputMismatchException e) {
    // ...
} catch (Exception e) {
    // ...
} finally {
    System.out.println("DONE");
}

Throwing Exceptions

throw and throws Clause

public class ExceptionThrowingExample {
    public static void main(String[] args) {
        try {
            doWork(5);
        } catch (Exception e) {
            System.out.println("Caught exception: " + e.getMessage());
        }
    }

    public static void doWork(int num) throws Exception {
        if (num != 5)
            throw new Exception("Invalid value");
        else
            System.out.println("Work done successfully!");
    }
}

Exception Types and Hierarchy

Throwable Class Hierarchy

List of Checked and Unchecked Exceptions

Checked Exceptions Unchecked Exceptions
IOException ArithmeticException
SQLException NullPointerException
ClassNotFoundException ArrayIndexOutOfBoundsException
IllegalAccessException IllegalArgumentException
… (and more) … (and more)

Handling Exceptions - Best Practices

Programmer-Defined Exceptions

Example 1

class MyException extends Exception {
    private int ex;

    MyException(int a) {
        ex = a;
    }

    public String toString() {
        return "MyException[" + ex + "] is less than zero";
    }
}

class Test {
    static void sum(int a, int b) throws MyException {
        if (a < 0)
            throw new MyException(a);
        else
            System.out.println(a + b);
    }

    public static void main(String[] args) {
        try {
            sum(-10, 10);
        } catch (MyException me) {
            System.out.println(me);
        }
    }
}

/* Output:
MyException[-10] is less than zero
*/

Assertions

Sample Use #1

public double deposit(double amount) {
    double oldBalance = balance;
    balance += amount ;
    assert balance > oldBalance;
}

public double withdraw(double amount) {
    double oldBalance = balance;
    balance -= amount;
    assert balance < oldBalance;
}

Sample Use #2

public double deposit(double amount) {
    double oldBalance = balance;
    balance += amount;
    assert balance > oldBalance : "Serious Error – balance did not increase after deposit";
}

Different Uses of Assertions

Precondition Assertions

public class Try {
    public static void main(String[] args) {
        int gender = 4;
        double parkingFee = 10.00;
        double tuition = 50.00;
        double totalFee;
        double roomAndBoard = 0.0;
        assert (gender == 1 || gender == 2) : "Invalid";
        switch (gender) {
            case 1:
                totalFee = tuition + parkingFee;
                System.out.println(totalFee);
                break;
            case 2:
                totalFee = tuition + roomAndBoard;
                System.out.println(totalFee);
                break;
        }
    }
}

Handling Checked Exceptions

When calling a method that can throw checked exceptions:

Handling Runtime Exceptions

When calling a method that can throw runtime exceptions, it is optional to use the try-catch statement or modify the method header to include a throws clause.

Throwing Exceptions – throw and throws clause

We can write a method that throws an exception directly using the throw reserved word to create a new instance of the Exception or its subclasses. The method header includes the reserved word throws to explicitly specify the exceptions that the method might throw.

public void doWork(int num) throws Exception {
    if (num != val)
        throw new Exception("Invalid val");
}

Running Programs with Assertions

To run the program with assertions enabled, use java –ea <main class>. If the -ea option is not provided, the program is executed without checking assertions.

How to Enable Assertions in NetBeans

  1. Right-click on your project name and select Properties.
  2. Click Run in the left side panel.
  3. At VM Options, type -ea.

Assertions (Continued)

Second Form of Assertions

The assert statement may also take the form:

assert <boolean expression>: <expression>;

where <expression> represents the value passed as an argument to the constructor of the AssertionError. The value serves as the detailed message of a thrown exception (customized error message).

Sample Use #2

public double deposit(double amount) {
    double oldBalance = balance;
    balance += amount;
    assert balance > oldBalance : "Serious Error – balance did not increase after deposit";
}

Different Uses of Assertions (Control Flow Invariant)

This statement documents the fact that the default case should never be executed when the program is running correctly.

assert false : "This should never happen";

Exception Types

Throwable Hierarchy

There are over 60 classes in the Throwable hierarchy.

Programmer-Defined Exceptions

Example 1

class MyException extends Exception {
    private int ex;

    MyException(int a) {
        ex = a;
    }

    public String toString() {
        return "MyException[" + ex + "] is less than zero";
    }
}

class Test {
    static void sum(int a, int b) throws MyException {
        if (a < 0)
            throw new MyException(a);
        else
            System.out.println(a + b);
    }

    public static void main(String[] args) {
        try {
            sum(-10, 10);
        } catch (MyException me) {
            System.out.println(me);
        }
    }
}

/* Output:
MyException[-10] is less than zero
*/

Assertions

Sample Use #1

public double deposit(double amount) {
    double oldBalance = balance;
    balance += amount ;
    assert balance > oldBalance;
}

public double withdraw(double amount) {
    double oldBalance = balance;
    balance -= amount;
    assert balance < oldBalance;
}

Sample Use #2

public double deposit(double amount) {
    double oldBalance = balance;
    balance += amount;
    assert balance > oldBalance : "Serious Error – balance did not increase after deposit";
}

Different Uses of Assertions

Precondition Assertions

public class Try {
    public static void main(String[] args) {
        int gender = 4;
        double parkingFee = 10.00;
        double tuition = 50.00;
        double totalFee;
        double roomAndBoard = 0.0;
        assert (gender == 1 || gender == 2) : "Invalid";
        switch (gender) {
            case 1:
                totalFee = tuition + parkingFee;
                System.out.println(totalFee);
                break;
            case 2:
                totalFee = tuition + roomAndBoard;
                System.out.println(totalFee);
                break;
        }
    }
}

Handling Checked Exceptions

When calling a method that can throw checked exceptions:

Handling Runtime Exceptions

When calling a method that can throw runtime exceptions, it is optional to use the try-catch statement or modify the method header to include a throws clause.

Throwing Exceptions – throw and throws clause

We can write a method that throws an exception directly using the throw reserved word to create a new instance of the Exception or its subclasses. The method header includes the reserved word throws to explicitly specify the exceptions that the method might throw.

public void doWork(int num) throws Exception {
    if (num != val)
        throw new Exception("Invalid val");
}

Running Programs with Assertions

To run the program with assertions enabled, use java –ea <main class>. If the -ea option is not provided, the program is executed without checking assertions.

How to Enable Assertions in NetBeans

  1. Right-click on your project name and select Properties.
  2. Click Run in the left side panel.
  3. At VM Options, type -ea.

Assertions (Continued)

Second Form of Assertions

The assert statement may also take the form:

assert <boolean expression>: <expression>;

where <expression> represents the value passed as an argument to the constructor of the AssertionError. The value serves as the detailed message of a thrown exception (customized error message).

Sample Use #2

public double deposit(double amount) {
    double oldBalance = balance;
    balance += amount;
    assert balance > oldBalance : "Serious Error – balance did not increase after deposit";
}

Different Uses of Assertions (Control Flow Invariant)

This statement documents the fact that the default case should never be executed when the program is running correctly.

assert false : "This should never happen";

Exception Types

Throwable Hierarchy

There are over 60 classes in the Throwable hierarchy.

Programmer-Defined Exceptions

Example 1

class MyException extends Exception {
    private int ex;

    MyException(int a) {
        ex = a;
    }

    public String toString() {
        return "MyException[" + ex + "] is less than zero";
    }
}

class Test {
    static void sum(int a, int b) throws MyException {
        if (a < 0)
            throw new MyException(a);
        else
            System.out.println(a + b);
    }

    public static void main(String[] args) {
        try {
            sum(-10, 10);
        } catch (MyException me) {
            System.out.println(me);
        }
    }
}

/* Output:
MyException[-10] is less than zero
*/

Assertions

Sample Use #1

public double deposit(double amount) {
    double oldBalance = balance;
    balance += amount ;
    assert balance > oldBalance;
}

public double withdraw(double amount) {
    double oldBalance = balance;
    balance -= amount;
    assert balance < oldBalance;
}

Sample Use #2

public double deposit(double amount) {
    double oldBalance = balance;
    balance += amount;
    assert balance > oldBalance : "Serious Error – balance did not increase after deposit";
}

Different Uses of Assertions

Precondition Assertions

public class Try {
    public static void main(String[] args) {
        int gender = 4;
        double parkingFee = 10.

00;
        double tuition = 50.00;
        double totalFee;
        double roomAndBoard = 0.0;
        assert (gender == 1 || gender == 2) : "Invalid";
        switch (gender) {
            case 1:
                totalFee = tuition + parkingFee;
                System.out.println(totalFee);
                break;
            case 2:
                totalFee = tuition + roomAndBoard;
                System.out.println(totalFee);
                break;
        }
    }
}

Handling Checked Exceptions

When calling a method that can throw checked exceptions:

Handling Runtime Exceptions

When calling a method that can throw runtime exceptions, it is optional to use the try-catch statement or modify the method header to include a throws clause.

Throwing Exceptions – throw and throws clause

We can write a method that throws an exception directly using the throw reserved word to create a new instance of the Exception or its subclasses. The method header includes the reserved word throws to explicitly specify the exceptions that the method might throw.

public void doWork(int num) throws Exception {
    if (num != val)
        throw new Exception("Invalid val");
}

Running Programs with Assertions

To run the program with assertions enabled, use java –ea <main class>. If the -ea option is not provided, the program is executed without checking assertions.

How to Enable Assertions in NetBeans

  1. Right-click on your project name and select Properties.
  2. Click Run in the left side panel.
  3. At VM Options, type -ea.