Easy Tutorial
❮ Net Serverfile Java Applet Basics ❯

Java Exception Handling

Exceptions are errors in a program, but not all errors are exceptions, and sometimes errors can be avoided.

For example, if your code is missing a semicolon, the result will be an error message java.lang.Error; if you use System.out.println(11/0), you will get a java.lang.ArithmeticException because you are dividing by zero.

There are many reasons for exceptions, usually including the following categories:

Some of these exceptions are caused by user errors, some by program errors, and others by physical errors.

To understand how Java exception handling works, you need to grasp the following three types of exceptions:


Hierarchy of Exception Classes

All exception classes are subclasses of the java.lang.Exception class.

The Exception class is a subclass of the Throwable class. In addition to the Exception class, Throwable has another subclass, Error.

Java programs typically do not catch errors. Errors usually occur in serious failures and are beyond the scope of Java program handling.

Error indicates errors that occur at runtime.

For example, JVM memory overflow. Generally, programs cannot recover from errors.

Exception classes have two main subclasses: IOException and RuntimeException.

In the built-in classes of Java (which will be explained next), there are many common checked and unchecked exceptions.


Built-in Exception Classes in Java

The Java language defines some exception classes in the java.lang standard package.

Subclasses of the standard runtime exception class are the most common exception classes. Since the java.lang package is loaded by default into all Java programs, most exceptions inherited from the runtime exception class can be used directly.

Java also defines some other exceptions based on various class libraries. The following table lists Java's unchecked exceptions.

Exception Description
ArithmeticException Thrown when an exceptional arithmetic condition has occurred. For example, an integer "divide by zero" throws an instance of this class.
ArrayIndexOutOfBoundsException Thrown to indicate that an array has been accessed with an illegal index. The index is either negative or greater than or equal to the size of the array.
ArrayStoreException Thrown to indicate that an attempt has been made to store the wrong type of object into an array of objects.
ClassCastException Thrown to indicate that the code has attempted to cast an object to a subclass of which it is not an instance.
IllegalArgumentException Thrown to indicate that a method has been passed an illegal or inappropriate argument.
IllegalMonitorStateException Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
IllegalStateException Signals that a method has been invoked at an illegal or inappropriate time. In other words, the Java environment or Java application is not in an appropriate state for the requested operation.
IllegalThreadStateException Thrown to indicate that a thread is not in an appropriate state for the requested operation.
IndexOutOfBoundsException Thrown to indicate that an index of some sort (such as to an array, to a string, or to a vector) is out of range.
NegativeArraySizeException Thrown if an application tries to create an array with negative size.
NullPointerException Thrown when an application attempts to use null in a case where an object is required.
NumberFormatException Thrown when an application tries to convert a string to a numeric type, but the string does not have an appropriate format.
SecurityException Thrown by the security manager to indicate a security violation.
StringIndexOutOfBoundsException Thrown by methods in the String class to indicate that an index is either negative or greater than the size of the string.
UnsupportedOperationException Thrown to indicate that the requested operation is not supported.

The table below lists the checked exception classes defined in the java.lang package in Java.

Exception Description
ClassNotFoundException Thrown when an application tries to load a class through its string name, but no definition for the class with the specified name could be found.
CloneNotSupportedException Thrown when the clone method in class Object is called to clone an object, but that object's class does not implement the Cloneable interface.
IllegalAccessException Thrown when an application tries to reflectively create an instance, set or get a field, or invoke a method, but the currently executing method does not have access to the definition of the specified class, field, method, or constructor.
InstantiationException Thrown when an application tries to create an instance of a class using the newInstance method in class Class, but the specified class object cannot be instantiated because it is an interface or an abstract class.
InterruptedException Thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is interrupted, either before or during the activity.
NoSuchFieldException Thrown if the specified field does not exist.
NoSuchMethodException Thrown if the specified method does not exist.

Exception Methods

The following list outlines the main methods of the Throwable class:

No. Method and Description
1 public String getMessage() <br> Returns a detailed message about the exception that has occurred. This message is initialized in the Throwable constructor.
2 public Throwable getCause() <br> Returns a Throwable object representing the cause of the exception.
3 public String toString() <br> Returns a short description of this Throwable.
4 public void printStackTrace() <br> Prints this Throwable and its backtrace to the standard error stream.
5 public StackTraceElement[] getStackTrace() <br> Returns an array containing stack trace elements. The zeroth element represents the top of the stack, and the last element represents the bottom of the method call stack.
6 public Throwable fillInStackTrace() <br> Fills in the execution stack trace, adding to any previous information.

Catching Exceptions

Exceptions can be caught using try and catch keywords. The try/catch block is placed where the exception is likely to occur.

The code within the try/catch block is referred to as protected code. The syntax for using try/catch is as follows:

try
{
   // Program code
}catch(ExceptionName e1)
{
   // Catch block
}

The catch statement contains the declaration of the type of exception to be caught. When an exception occurs within the protected code, the catch block that follows the try block is checked.

If the exception that occurred is included in the catch block, it is passed to the catch block, similar to passing an argument to a method.

Example

The following example declares an array with two elements and attempts to access the fourth element, which throws an exception.

ExcepTest.java File Code:

// File name : ExcepTest.java
import java.io.*;
public class ExcepTest{

   public static void main(String args[]){
      try{
         int a[] = new int[2];
         System.out.println("Access element three :" + a[3]);
      }catch(ArrayIndexOutOfBoundsException e){
         System.out.println("Exception thrown  :" + e);
      }
      System.out.println("Out of the block");
   }
}

The above code, when compiled and run, produces the following output:

Exception thrown  :java.lang.ArrayIndexOutOfBoundsException: 3
Out of the block

Multiple Catch Blocks

A try block can be followed by multiple catch blocks, which is known as multiple catch blocks.

The syntax for multiple catch blocks is as follows:

try{
   // Program code
}catch(ExceptionType1 e1){
  // Program code
}catch(ExceptionType2 e2){
  // Program code
}catch(ExceptionType3 e3){
  // Program code
}

The code snippet above contains 3 catch blocks.

You can add any number of catch blocks after a try statement.

If an exception occurs within the protected code, it is thrown to the first catch block.

If the data type of the thrown exception matches ExceptionType1, it will be caught here.

If it does not match, it will be passed to the second catch block.

This continues until the exception is caught or it passes through all the catch blocks.

Example

This example demonstrates how to use multiple try/catch blocks.

try {
    file = new FileInputStream(fileName);
    x = (byte) file.read();
} catch(FileNotFoundException f) { // Not valid!
    f.printStackTrace();
    return -1;
} catch(IOException i) {
    i.printStackTrace();
    return -1;
}

throws/throw Keywords:

If a method does not catch a checked exception, the method must declare it using the throws keyword. The throws keyword appears at the end of a method's signature.

You can also throw an exception using the throw keyword, whether it is newly instantiated or just caught.

The following method declaration throws a RemoteException:

import java.io.*;
public class className
{
  public void deposit(double amount) throws RemoteException
  {
    // Method implementation
    throw new RemoteException();
  }
  // Remainder of class definition
}

A method can declare to throw multiple exceptions, separated by commas.

For example, the following method declares to throw RemoteException and InsufficientFundsException:

import java.io.*;
public class className
{
   public void withdraw(double amount) throws RemoteException,
                              InsufficientFundsException
   {
       // Method implementation
   }
   // Remainder of class definition
}

finally Keyword

The finally keyword is used to create a block of code that follows a try block.

The code in the finally block will always be executed regardless of whether an exception occurs.

In the finally block, you can run cleanup or finalization code.

The finally block appears after the catch block, with the following syntax:

try{
  // Program code
}catch(ExceptionType1 exceptionVariable1){
  // Program code
}catch(ExceptionType2 exceptionVariable2){
  // Program code
}finally{
  // Program code
}

Example

ExcepTest.java File Code:

public class ExcepTest{
  public static void main(String args[]){
    int a[] = new int[2];
    try{
       System.out.println("Access element three :" + a[3]);
    }catch(ArrayIndexOutOfBoundsException e){
       System.out.println("Exception thrown  :" + e);
    }
    finally{
       a[0] = 6;
       System.out.println("First element value: " +a[0]);
       System.out.println("The finally statement is executed");
    }
  }
}

The above example compiles and runs with the following result:

Exception thrown  :java.lang.ArrayIndexOutOfBoundsException: 3
First element value: 6
The finally statement is executed

Note the following:


try-with-resources

After JDK7, Java introduced the try-with-resources syntactic sugar to open resources and ensure that each resource is automatically closed after the statement execution.

Before JDK7, all opened system resources, such as streams, files, or Socket connections, needed to be manually closed by the developer, otherwise it would lead to resource leakage.

try (resource declaration) {
  // using the resource
} catch (ExceptionType e1) {
  // exception block
}

In the above syntax, try is used to declare and instantiate resources, and catch is used to handle any exceptions that may be thrown when closing the resources.

Note: The try-with-resources statement closes all resources that implement the AutoCloseable interface.

Example

import java.io.*;

public class tutorialproTest {

    public static void main(String[] args) {
        String line;
        try(BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
            while ((line = br.readLine()) != null) {
                System.out.println("Line =>"+line);
            }
        } catch (IOException e) {
            System.out.println("IOException in try block =>" + e.getMessage());
        }
    }
}

The output of the above example is:

IOException in try block =>test.txt (No such file or directory)

In the above example, we instantiate a BufferedReader object to read data from the test.txt file.

Declaring and instantiating the BufferedReader in the try-with-resources statement ensures that the resource is closed after the statement execution, regardless of whether the try statement completes normally or abruptly.

If an exception occurs, it can be handled using the catch block.

Now, let's see what it looks like without using try-with-resources and instead using finally to close the resource. The overall code is much more extensive and complex:

Example

import java.io.*;

class tutorialproTest {
    public static void main(String[] args) {
        BufferedReader br = null;
        String line;

        try {
            System.out.println("Entering try block");
            br = new BufferedReader(new FileReader("test.txt"));
            while ((line = br.readLine()) != null) {
                System.out.println("Line =>"+line);
            }
        } catch (IOException e) {
            System.out.println("IOException in try block =>" + e.getMessage());
        } finally {
            System.out.println("Entering finally block");
            try {
                if (br != null) {
                    br.close();
                }
            } catch (IOException e) {
                System.out.println("IOException in finally block =>"+e.getMessage());
            }
        }
    }
}
Entering try block
IOException in try block => test.txt (No such file or directory)
Entering finally block

Handling Multiple Resources with try-with-resources

The try-with-resources statement can declare multiple resources by separating them with semicolons ;:

Example

import java.io.*;
import java.util.*;
class tutorialproTest {
    public static void main(String[] args) throws IOException{
        try (Scanner scanner = new Scanner(new File("testRead.txt")); 
             PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) {
            while (scanner.hasNext()) {
                writer.print(scanner.nextLine());
            }
        }
    }
}

This example uses a Scanner object to read a line from the file "testRead.txt" and writes it to a new file "testWrite.txt".

When multiple resources are declared, the try-with-resources statement closes these resources in the reverse order. In this case, the PrintWriter object is closed first, followed by the Scanner object.


Declaring Custom Exceptions

In Java, you can define your own exceptions. Keep the following points in mind when writing your own exception classes:

You can define your own exception class as follows:

class MyException extends Exception{
}

Inheriting from the Exception class creates a checked exception class.

The following InsufficientFundsException class is a user-defined exception class that extends Exception.

An exception class, like any other class, contains variables and methods.

Example

The following example simulates a bank account, identified by the card number, allowing deposit and withdrawal operations.

InsufficientFundsException.java File Code:

// File name InsufficientFundsException.java
import java.io.*;

// Custom exception class, inheriting from Exception class
public class InsufficientFundsException extends Exception
{
  // The amount here stores the deficiency when an exception occurs (withdrawing more than the balance)
  private double amount;
  public InsufficientFundsException(double amount)
  {
    this.amount = amount;
  } 
  public double getAmount()
  {
    return amount;
  }
}

To demonstrate how to use our custom exception class,

the following CheckingAccount class includes a withdraw() method that throws an InsufficientFundsException.

CheckingAccount.java File Code:

// File name CheckingAccount.java
import java.io.*;

// This class simulates a bank account
public class CheckingAccount
{
  // balance is the balance, number is the card number
   private double balance;
   private int number;
   public CheckingAccount(int number)
   {
      this.number = number;
   }
  // Method: Deposit money
   public void deposit(double amount)
   {
      balance += amount;
   }
  // Method: Withdraw money
   public void withdraw(double amount) throws InsufficientFundsException

InsufficientFundsException { if(amount <= balance) { balance -= amount; } else { double needs = amount - balance; throw new InsufficientFundsException(needs); } } // Method: Return balance public double getBalance() { return balance; } // Method: Return card number public int getNumber() { return number; }

The BankDemo program demonstrates how to call the deposit() and withdraw() methods of the CheckingAccount class.

BankDemo.java File Code:

// File name BankDemo.java
public class BankDemo
{
   public static void main(String [] args)
   {
      CheckingAccount c = new CheckingAccount(101);
      System.out.println("Depositing $500...");
      c.deposit(500.00);
      try
      {
         System.out.println("\nWithdrawing $100...");
         c.withdraw(100.00);
         System.out.println("\nWithdrawing $600...");
         c.withdraw(600.00);
      }catch(InsufficientFundsException e)
      {
         System.out.println("Sorry, but you are short $"
                              + e.getAmount());
         e.printStackTrace();
      }
   }
}

Compile the above three files and run the BankDemo program, the result is as follows:

Depositing $500...

Withdrawing $100...

Withdrawing $600...
Sorry, but you are short $200.0
InsufficientFundsException
        at CheckingAccount.withdraw(CheckingAccount.java:25)
        at BankDemo.main(BankDemo.java:13)

Common Exceptions

In Java, two types of exceptions and errors are defined.

❮ Net Serverfile Java Applet Basics ❯