Exception Handling

Lesson 303.12 Exception Handling

Learning Objectives:

By the end of lesson, learners will be able to:

  • Describe Exception and Exception Handling.

  • Describe Java Exception Classes Hierarchy.

  • Demonstrate how to use Exceptions in Java with defined keywords.

  • Declare Exceptions in Java using defined keywords.

  • Create user-defined Exceptions.

Section 1 ---------------------------------

Exception Handling

Table of Contents

  • Topic 1: Exception Overview.

  • Topic 2: Exception Handling Overview.

  • Topic 3: Exception Categories.

  • Topic 4: Difference Between Error and Exception.

  • Topic 5: Java Exception Class Hierarchy.

  • Topic 6: Exception Class Methods.

  • Topic 7: Built-in Java Exceptions.

  • Topic 8: Accounting for an Exception.

  • Topic 9: Try-Catch Block Overview.

  • Topic 10: Catching Multiple Exceptions.

  • Topic 11: Nested Try Blocks.

  • Topic 12: Throws and Throw Keywords.

  • Topic 12a: Why we need the Throws Keyword.

  • Topic 13: User-defined Exception.

Introduction

In this lesson, we will identify an Exception, discuss the types of Exceptions and their classes, and demonstrate Exception Handling.

Topic 1: Exception Overview

  • The term Exception is used (short) for the phrase "exceptional event."

  • An exception is an event or abnormal condition that may happen at runtime, and disrupts the normal flow of the program. We can handle exceptions to ensure our code gets executed normally. Click here for more information about Exception.

Topic 2: Exception Handling Overview

  • Exception Handling in Java helps to minimize exceptions and helps to recover from exceptions. It is one of the powerful mechanisms for handling runtime and compile exceptions, allowing for the normal flow and maintenance of the application, making them bug-free.

  • It is an object, which is thrown at runtime.

  • Five keywords are used in Exception Handling: try, catch, finally, throws, and throw (note that there is a difference between throw and throws).

Exception Handling Advantages/Benefits

  • Separates the error handling code from normal code.

  • Differentiates the error types.

  • Maintains the normal flow of the program.

Topic 3: Exception Categories

There are three main Exception categories:

  • Checked (also called IOException)

    • Exceptions that are checked at compile-time by compiler - the programmer is prompted to handle these exceptions.

    • A checked exception forces you to either use a try-catch or throws keyword. All exceptions are checked exceptions except Error, Uncheck Exception (Runtime Exception), and their subclasses.

      • Example: IOException, ClassNotFoundException, SQLException, etc.

  • Unchecked (also called Runtime Exception)

    • Exceptions that are checked at run-time by compiler - a runtime exception happens due to a programming error.

    • An unchecked exception does not force you to either use try-catch or throws keyword. RuntimeException and their subclasses are unchecked exceptions. This Exception can be avoided by programmer.

      • Example: ArithmeticException, NullPointerException, etc.

  • Error: Error is irrecoverable. Some examples of errors are OutOfMemoryError, VirtualMachineError, and AssertionError.

Topic 4: Difference Between Error and Exception

  • Errors indicate that something severe has gone wrong; if so, the application should crash rather than try to handle the error. Errors are usually beyond the control of the programmer; therefore, programmers should not try to handle errors.

  • Exceptions are events that occur in the code. A programmer can handle such conditions and take necessary corrective actions. For example:

    • NullPointerException – When you try to use a reference that points to null.

    • ArithmeticException – When bad data is provided by user. For example, when you try to divide a number by zero, this exception occurs because dividing a number by zero is undefined.

    • ArrayIndexOutOfBoundsException – When you try to access the elements of an array out of its bounds. For example, if an array size is 5 (five elements) and you are trying to access the 10th element, you cannot because the elements are out of its bounds.

Topic 5: Java Exception Class Hierarchy

Topic 5: Java Exception Classes Hierarchy (continued) Hierarchy in Java Exception Handling:

  • Throwable Class –

    • Is the root class for the exception hierarchy in Java.

    • Is in the java.lang package.

  • Error Class –

    • Subclass of Throwable.

    • Consists of abnormal conditions that are out of one’s control and depend on the environment.

    • Cannot be handled, and will always result in the halting of the program.

      • Example: StackOverFlowError that can occur in an infinite loop or recursion.

  • Exception Class–

    • Subclass of Throwable.

    • Consists of abnormal conditions that can be handled explicitly.

    • If exceptions are handled, code will continue to execute smoothly. Click here for more information about Throwable Class.

Topic 6: Exception Class Methods

Exception class does not declare its methods; it inherits Throwable class methods.

Method PrototypeDescription

public String getMessage()

Get a detailed message about the exception that occurred.

public Throwable getCause()

Get the cause of the exception represented by a throwable object.

public String toString()

Concatenates the name of the class with the result of getMessage(), and returns the resultant string.

public void printStackTrace()

Prints the result of toString() and the contents of stack trace to the error output stream, System.err.

public StackTraceElement [] getStackTrace()

Get each element in the stack trace in the form of an array.

public Throwable fillInStackTrace()

Fill the stack trace with the current stack trace.

Topic 7: Built-In Java Exceptions

Here is a list of common Java Exceptions:

Java ExceptionDescription

ArithmeticException

Arithmetic error (divide-by-zero).

ArrayIndexOutOfBoundsException

Array index is out-of-bounds.

IllegalArgumentException

Illegal argument used to call a method.

IllegalThreadStateException

Requested operation not compatible with current thread state.

IndexOutOfBoundsException

Some type of index is out-of-bounds.

NullPointerException

Invalid use of a null reference.

NumberFormatException

Invalid conversion of a string to a numeric format.

StringIndexOutOfBoundsException

Attempt to index outside the bounds of a string.

TypeNotPresentException

Type not found.

Topic 8: Accounting for an Exception

Java’s Exception Handling consists of three operations:

  • Declaring Exceptions

  • Catching an Exception

  • Throwing an Exception

public void methodC() {  // no exception declared
  public void methodD() throws XxxException, YyyException {
   ......
  }
// method body throw XxxException and YyyException
try {
  ......
  // uses methodD() which declares XxxException &
YyyException
  methodD();
  ......
   } catch (XxxException ex) {
    public void methodD() throws XxxException, YyyException {   // method's signature
  // Exception handler for XxxException
  ......
  // method's body
  } catch (YyyException ex} {
  // XxxException occurs
  // Exception handler for YyyException
  if ( ... )
  ......
  // construct an XxxException object,throw to JVM
   } finally {   // optional
    ...
}
throw new XxxException(...);
// These codes always run, used for cleaning up
  }
......
}
......
  // YyyException occurs
  if ( ... )
    // construct an YyyException object, throw to JVM
  throw new YyyException(...);   ...

Topic 9: Try-Catch Block Overview

Basic Syntax: Try-Catch Block

  • The try block contains the code you would like to execute if an exception occurs.

  • The catch block cannot be used without the try block.

  • catch: can be followed by a finally block later.

  • If none of the statements in the try block generate an exception, the catch block is skipped.

  • The finally block is executed after the try-catch block. Otherwise, it is executed after the try block. For each try block, there can be only one finally block.

try {
//code
}
catch (ExceptionType1 e1) {
// catch block for ExceptionType1 exception
}
catch (ExceptionType2 e2) {
// catch block for ExceptionType2 exception
}
finally {
// finally block always executes
}

Try-Catch Block Overview (continued)

  • A finally block contains all of the crucial statements that must be executed whether an exception occurs or not. The statements present in this block will always execute regardless of whether exception occurs in a try block or not, such as closing a connection, a stream, etc.

  • The finally block is optional. It is used to execute the program whether an exception is handled or not, which means that the finally block is always executed no matter whether there is an exception or not.

Example: ArithmeticException

Create a new class named ArithmeticExceptiondemo and write the code below in that class.

public class MyRunner {
public static void main(String[] args) { try {
int d = 0;
int n = 5;
 // code that generates exception
int divideByZero = n / d; }
catch (ArithmeticException e) {
System.out.println("ArithmeticException occur => " + e.getMessage()); e.printStackTrace();
}
finally {
System.out.println("This is the finally block"); }
}}

In this example, we will demonstrate how to declare and initialize Exception Handling for Arithmetic numbers in our program. Note: The AritmeticException Object “e” carries information about the exception that has occurred, which can be useful in taking recovery actions. If you initialize a Positive Number to variable d, you will not get an Exception; only finally block will execute.

Output:

ArithmeticException occur => / by zero
java.lang.ArithmeticException: / by zero
     at MyRunner.main(MyRunner.java:6)
This is the finally block

Example: ArrayIndexOutOfBoundsException

Create a new class named ArrayIndexOutOfBoundsExceptiondemo and write the code below in that class.

public class ArrayIndexOutOfBoundsExceptiondemo { public static void main(String[] args) {
try {
String[] st = {"A","B","C","D","E"}; st[11] = "X";
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("index position is not exsist --> " + e.getMessage()); // e.printStackTrace();
}
finally {
System.out.println("This is the finally block"); }
} }

Note: The ArrayIndexOutOfBoundsException Object “e” carries information about the exception that has occurred, which can be useful in taking recovery actions.

Example: NullPointerException

In this example, we will demonstrate how to handle NullpointExeption. Create a new class named NullPointerExceptiondemo and write the code below in that class.

public class NullPointerExceptiondemo { public static void main(String[] args) {
// Initializing String variable with null value
String ptr = null;
// Checking if ptr.equals null or works fine.
try {
// This line of code throws NullPointerException // because ptr is null
if (ptr.equals("hello"))
    System.out.print("Same");
else
    System.out.print("Not Same");
        }
catch(NullPointerException e)
{
    System.out.print("NullPointerException Caught => " + e.getMessage());
} }
}

Note: The NullPointerException Object “e” carries information about the exception that has occurred which can be useful in taking recovery actions.

Output:

NullPointerException Caught => Cannot invoke "String.equals(Object)"
because "<local1>" is null

Exception Message

Each exception contains a message at the level it was thrown. This message contains what went wrong, and identifies the line where the exception occurred. To view all of the messages from every level, use printStackTrace() method:

try {
// block of code to monitor for errors
} catch (Exception one){
// handle for Exception one
e.printStackTrace();
} finally{
// Exception message
// always execute
}

Topic 10: Catching Multiple Exceptions

You can actually catch Exceptions at two different levels:

  1. The Exact Exception:

    • For example: ArrayIndexOutOfBoundsException.

  2. A Parent Exception:

    • For example: IOException.

Note: The parent of all Exceptions is called “Exception.” If you would like to catch all exceptions, this can be used. Although it makes things easier to code, it is harder to pinpoint the reason behind the exception.

Topic 10: Catching Multiple Exceptions (continued)

On the flip slide, you can make debugging a lot easier by catching different exceptions. For example:

Basic Syntax

try {
// block of code to monitor for errors
} catch (ExceptionOne ex){
// handle for ExceptionOne exception
} catch (ExceptionTwo ex){
// handle for ExceptionTwo exception
} finally{
// Exception message
// Exception message
// always execute
}

Catching Multiple Exceptions.

Create a new class named MultipleExceptionExample and write the code below in that class. In this example, we will demonstrate how we can handle more than one exception at the same time.

public class MultipleExceptionExample {
    public static void main(String[] args) {
        int[] nums = {3,0,7,9};
        try{
            int x = nums[0]/nums[1];
            System.out.println(x);
            // this will throw an ArithmeticException
            int y = nums[10]; // this would throw an ArrayIndexOutOfBoundsException
            String s = null;
            s.length(); // this will throw Nullpointexception
        }
        catch(ArithmeticException eAri){
            System.out.println("Exection caught: numerator must be greather then Zero " + eAri);
            eAri.printStackTrace();
        }
        catch(ArrayIndexOutOfBoundsException eArr){
            System.out.println("Exection caught: You are exceed the array size " + eArr);
            eArr.printStackTrace();
        }
        catch(NullPointerException enull) {
            System.out.println("Exection caught:String length is Zero " + enull);
        }
        catch(Exception e){
            System.out.println("Exection caught: You got Error please try again" + e);
        }
        finally{
            System.out.println("finally block us always execute");
        }
    }
}

Nested Try Blocks

Try/catch blocks can be nested within each other. If an Exception is not caught within the nested try block, the outer try block is able to catch it. Outer blocks can be used as another default option. For example, an inner try block will try to handle an error gracefully, but if it cannot, the outer block can catch it and terminate the program.

try{
    // block of code to monitor for errors
} catch (Exception one){
    // handle for Exception one
    try {
        // block of code - nested try
    } catch {
        // handle any exception that occur inside the nested try
} }

Throws and Throw Keywords

  1. throws: The throws keyword is used to implicitly throw an exception, and is mainly used to throw checked exception. We can use/declare the throws keyword with only the method signature.

public static void method() throws NullPointerException, FileNotFoundException {
 //code
}
  1. throw: The throw keyword is used to manually/explicitly throw an exception, and we can define our own set of conditions or rules. We can use/declare the throw keyword within the method body or any block of code. We cannot throw multiple exceptions.

throw new ArithmeticException("dividing a number by 5 is not allowed in this program");

Why We Need the Throws Keyword

The throws keyword is used for handling checked exceptions. By using throws, we can declare multiple exceptions at one time. The throws keyword does the same thing that try-catch does but there are some cases where you would prefer throws over try-catch. For example, should you have several methods that can cause exceptions, it would be tedious to write try-catch for each method. The code will become unnecessarily long and will be less-readable.

Example: throws Keyword

Step 1: Create a class named Example_Throw, and write the below code. We will use the throws keyword in this class with the method signature.

import java.io.*;
public class Example_Throw {
    //declare exception using throws in the method signature
    public static void testMethod(int num) throws IOException, ArithmeticException{
        if(num==1)
            throw new IOException("IOException Occurred");
        else
            throw new ArithmeticException("ArithmeticException");
    }
}

Step 2: Create a class named myRunner.

public class myRunner {
    public static void main(String args[]) {
        //this try block calls the above method so handle the exception
        try{
            Example_Throw obj=new Example_Throw();
            obj.testMethod(1);
        }
        catch(Exception ex){
            System.out.println(ex);
        }
    }
}

Why We Need the Throw Keyword

The throw keyword is used to explicitly throw a single exception. When an exception is thrown, the flow of program execution transfers from the try block to the catch block. We use the throw keyword within a method. The throw keyword can also be used for throwing custom exceptions.

throw new ArithmeticException("dividing a number by 5 is not allowed in this program");

Example: Throw Keyword

Step 1: Create a class named Studentinfo, and write the code below. We will use throw keyword in the class within a method.

public class Studentinfo {
    public void checkEligibility(int StAge, double StGpa) {
        if(StAge < 18 && StGpa < 2) {
            throw new ArithmeticException("Student is not eligible for registration");
        }
        else{
            System.out.println("Student is eligible for registration");
        }
    }
}

Step 2: Create a class named StudentRunnerClass. We will define productCheck() method in this class, and we will create an instance of ProductInfo class, and then invoke the productCheck() method. If the weight value is less than 100, that method will throw an Exception (InvalidProductException).

public class StudentRunnerClass {
    public static void main(String[] args) {
        System.out.println("Welcome to the Registration process");
        Studentinfo st = new Studentinfo();
        st.checkEligibility(16, 1.6);
        System.out.println("Have a nice day..");
    }
}

User-Defined Exception

Java user-defined exception is an exception, and throws that exception using a keyword 'throw.' It is done by extending a class 'Exception.' In very large projects, creating a custom exception with an easily identifiable name could save coders time in several ways. Creating a custom exception is simple and can be performed this way:

Exception custom;

After you create your custom Exception, you can throw it in the exact same way as a regular Exception.

Example 1: Creating a Custom Exception

Step 1: Create a class named MyCustomerException, and write the code below. We will declare Custom Exception in this class, and we will extend the Exception class, which means that the Exception class becomes a SuperClass.

public class MyCustomerException extends Exception {
    String str1;
    public MyCustomerException(String str2) {
        // Call constructor of parent Exception
        super(str2);
        this.str1=str2;
    }
    public String toString(){
        return (" --->> MyException Occurred: "+str1) ;
    }
}

Step 2: Create a class named MyRunnerException, and write the code below:

public class MyRunnerException {
    public static void main(String args[]) {
        System.out.println("Starting of try block");
        try{
            // I'm throwing the custom exception using throw
            throw new MyCustomerException("This is My error Message");
        }
        catch(MyCustomerException exp){
            System.out.println(" -->> Catch Block") ;
            System.out.println(exp) ;
        }
    }
}

Example 2: Creating a Custom Exception

Step 1: Create a class named InvalidProductException, write the code below. We will declare a custom exception in this class; for that, we will extend Exception class, which means that the Exception class becomes a SuperClass.

public class InvalidProductException extends Exception {
    public InvalidProductException(String s) {
        // Call constructor of parent Exception
        super(s);
    }
}

Step 2: Create a class named ProductInfo, and write the code to the productCheck() method. We will use both the throws keyword and the throw class.

public class ProductInfo {
    public void productCheck(double weight) throws InvalidProductException {
        if(weight<100){
            throw new InvalidProductException("Product weight is exceed");
        }
    }
}

Step 3: Create a class named ProductAppRunner. We will define productCheck() method in this class, and we will create an instance of ProductInfo class, and then invoke the productCheck() method. If the weight value is less than 100, that method will throw an Exception (InvalidProductException).

public class ProductAppRunner {
    public static void main(String args[]) {
        ProductInfo obj = new ProductInfo();
        try{
            obj.productCheck(60);
        }
        catch (InvalidProductException ex) {
            System.out.println("Caught the exception");
            System.out.println(ex.getMessage());
        }
    }
}

throw vs. throws

throwthrows

Used to create a new Exception object and throw it.

Used in method definition to declare that a risky method is being called.

Used to explicitly throw an exception.

Implicitly throw an exception and works similarly to the try-catch block.

Can declare only one Exception at a time.

Can declare multiple Exceptions at a time.

Example: throw new IOException (“can not open connection”);

Example: throws IOException, ArrayIndexBoundException;

Practice Assignment

  • Find the assignment PA 303.12.1- Practice Assignment - Exception handling on Canvas under Assignment section.

  • If you have any technical questions while performing this assignment, ask the instructor for assistance.

Knowledge Checks

  1. What is the difference between an Exception and an Error in Java?

  2. How can you handle Exceptions in Java?

  3. Name the different types of Exceptions in Java

  4. Can we just use try instead of finally to catch blocks?

  5. Can we throw an exception explicitly or manually?

  6. In which situation will you not be able to execute the finally block?

  7. Suppose there is a catch block in tune with a try block with three statements - #1, #2, and #3. Now, imagine that the statement is thrown in statement #2. Will there be an execution of statement #3?

Summary

  • An Exception is an unwanted event that interrupts the normal flow of the program. When an Exception occurs, program execution gets terminated. In such cases, we get a system-generated error message.

  • The good thing about Exceptions is that they can be handled in Java.

  • By handling the Exceptions, we can provide a meaningful message to the user about the issue rather than a system-generated message, which the user may not understand.

  • Five keywords are used in Exception Handling: try, catch, finally, throws, and throw (note that there is a difference between throw and throws).

References

Last updated