Exception handling in Java is a technique of processing problems that occur during the execution of the program. Using exception handling, we can test the code and avoid it from exiting abruptly.
Exception handling in Java is accomplished using five keywords: try, catch, throw, throws and finally.
To understand what exceptions are and how to handle them, let us consider a program that displays two integers’ quotient.
//Divide by zero exception import java.util.Scanner;//program uses Scanner class public class Main { public static void main(String[] args){ int x,y; //create scanner object to obtain input from keyword Scanner input =new Scanner(System.in); System.out.print("Enter first integer = "); x = input.nextInt();//Read first integer System.out.print("Enter Second integer = "); y = input.nextInt();//Read second integer System.out.println(x +"/"+y+" = "+(x/y)); } }Output :
Now suppose we re-execute the program with values x = 5 and y = 0. An integer cannot be divided by 0, so Java raises an exception
Exception in thread "main" java.lang.ArithmeticException:/ by zero at DivideByZeroDemo.main (DivideByZeroDemo.java:l4)which displayed on the screen and execution of the program is stopped.
On carefully examining the exception that is displayed, we notice that in the exception, java.lang ArithmeticException is the name of the exception. It is followed by the text / by zero, which indicates that this exception occurred due to an attempt to divide by zero. It also includes the classname and method (DivideByZeroDemo.main) followed by the filename (DivideByZeroDemo.java) and the line number at which the exception raised (i.e.14).
In this example, since we have not provided an exception handler, the exception is handled by the Java runtime system’s default exception handler. The default exception handler displays information about the exception and stops the execution of the program.
Instead of depending upon the default exception handler for handling exceptions, Java language allows you to handle the exception that occurs during the program’s execution. It is done using the try-catch-finally structure. Doing so helps fix the problem that leads to the exception and prevents the program from ending abruptly.NOTE: A floating-point number when divided by 0 does not raise an exception.
try-catch-finally STRUCTURE
The Java statements that deal with exception handling described in the following sections. The general syntax of the try-catch-finally statement is as shown below:
try { //java statements capable of throwing exceptions } catch (Exception_1 e) { //java statements to handle the exception Exception_1 } finally { //cleanup code or exit code (optional) }Try block
The try block starts with the keyword try followed by a set of statements enclosed in curly braces {}. The statements in a program that may raise an exception(s) placed within a try block. A try block is a group of Java statements, which are to check for exceptions.
To handle a run-time error and monitor the results, we merely enclose the code inside a try block. If an exception occurs within the try block, it is handled by the appropriate exception handler (catch block) associated with the try block. If there are no exceptions to be thrown, try to return the result of executing the block. A try block should have one (or more) catch block(s) or one finally block, or both. If neither is present, a compiler error occurs which says ‘try’ without ‘catch’ or ‘finally.’
Exception handlers are associated with a try block by providing one (or more) catch block(s) directly after the try block.
Catch block
Immediately following a try block is a sequence of catch blocks. A catch block is a group of Java statements, enclosed in braces {} which are used to handle a specific exception that has been thrown. Catch blocks (or handlers) should be placed after the try block. That is, a catch clause follows immediately after the try block.
If an exception occurs during the try block’s execution, the JVM immediately stops executing the try block and looks for a catch block that can process that type of exception. Any remaining statements in the try block are not executed. On the occurrence of an exception, the control first shifts to the first catch block. Suppose the type of the exception that occurred matches the type of the catch block parameter or a superclass type of the exception. In that case, statements that are part of that catch block are executed, the remaining catch blocks bypassed, and the exception continues with the statements following the last catch block. Otherwise, the remaining catch blocks are examined in sequence for a type match.
If the matching catch block has not been located, the default exception handler will display the exception and terminate the program. The finally block is optional; it contains the code that must execute regardless of whether an exception occurs. If it is present, it is placed after the last catch block.
A catch block is specified by the keyword catch, followed by a single argument within parentheses (). The argument type in a catch clause is from the Throwable class or one of its sub-classes. Java initializes the argument (parameter) to refer to the caught object. The program illustrates the use of try-catch statements.Program Using the try-catch statements.
//use of try catch import java.util.Scanner; public class Main { public static void main(String[] args) { int x,y; //create scanner object to obtain input from keyword Scanner input = new Scanner(System.in); try { System.out.println("Try Block Entered"); System.out.print("Enter first integer = "); x = input.nextInt(); //Read first integer System.out.print("Enter Second integer = "); y = input.nextInt(); //Read second integer System.out.println(x + "/" +y+" = "+(x/y)); System.out.println("Try Block Ended"); } catch(ArithmeticException e) { System.out.println("Denominator cannot be zero while integer division"); } System.out.println("Statement after try catch block"); } }Explanation: This program aims to display the result of the division of two integer numbers and check for division by zero exception. When the user enters the values 7 and 2 for x and y respectively, no exception throw and output be
Statements After try to catch blockHowever; when the user enters the values 5 and 0 for x and y respectively, then the JVM on encountering the statement.
System.out println(x + "/" + y + "=" '+ (x/y));Which contains the arithmetic expression (x/y) throw an ArithmeticExeption exception. The execution of the code inside the try stops, and the attached catch block is examined. Since the type of the exception (i.e., ArithmeticExeption) that occurred matches the type of the catch block parameter, so the statement.
System.out.println(“Denominator cannot be zero while integer division”); is executed. After the catch block has been executed, execution then continues with the statement following the catch block. The output generatedtry block entered Enter first integer = 5 Enter second integer = 0 The denominator cannot be zero while integer division After try blockFinally block
The final step in setting up an exception handler is providing a mechanism for cleaning up the program before control is passed to a different part of the program. It can be achieved by enclosing the clean-up logic within the finally block. It is described in the following way.
The code within the finally block always executed regardless of what happens within the try block. If no exceptions are thrown, then no part of the code in the catch blocks is executed, but the code in the finally block is executed.
If an exception is thrown, first the code in the corresponding catch block (exception handler) is executed and then the control is passed to the finally block, and the code in the finally block is executed. Note that there is only one finally block per one try block. The program illustrates the use of try-catch-finally statements.• Program Using the try-catch-finally statements.
public class Main { public static void main(String[] args){ System.out.println("Program Execution starts here\n"); int a, b, c; try{ a = java.lang.Integer.parseInt(args[0]); b = java.lang.Integer.parseInt(args[1]); c = a/b; System.out.println( a +"/"+ b +"="+ c); } catch(Exception e) { System.out.println( e); } finally { System.out.println("Finally blocks always get executed"); } System.out.println("\n Program Execution completes here"); } }The output of Program is given below:
C:\javatest>java Divide 4 2 Program Execution starts here 4/2 = 2 Finally blocks always get executed Program Execution completes here C:\javatest>java Divide 4 0 Program Execution starts here java.lang.ArithmeticException: / by zero Finally blocks always get executed Program Execution completes hereGenerally, the finally block is used to close the files that have been opened, connections to the databases that have been opened, sockets in the networks that have been opened or for releasing any system resources. If the code in the catch block terminates the program by executing System.exit (0), the code in the finally block will not be executed.
In the above code listing, a temporary file is created in the try block, and the block also has some code that can potentially throw an exception. Irrespective of whether the try block succeeds, the temporary file has to be closed and deleted from the file system. It is accomplished by closing and deleting the file in the finally block.Multiple catch blocks
Typically, the code in a try-block can throw more than one kind of exception. If this is the case, you can put several catch blocks after the try block to handle them, one for each possible exception. When an exception is generated, the JVM searches the catch blocks in order. The first catch block with a parameter that matches the exception thrown execute, any remaining catch blocks skipped.
The program illustrates the use of multiple catch blocks associated with a single try block.Program Using multiple catch blocks.
public class Main { public static void main(String[] args){ System.out.println("Program Execution starts here\n"); int a, b, c; try{ a = java.lang.Integer.parseInt(args[0]); b = java.lang.Integer.parseInt(args[1]); c = a/b; System.out.println( a +"I"+ b +"="+ c); } catch(NumberFormatException e){ System.out.println("Arguments passed should be valid Numbers"); } catch(ArithmeticException e){ System.out.println("Second Argument Should not be Zero"); } catch(ArrayIndexOutOfBoundsException e){ System.out.println("Pass Proper Arguments"); } System.out.println("\n Program Execution Completes here"); } }To see how Program responds to different inputs, the reader can run the program by giving inputs such as (4, 2), (4, a), (4, 0) etc.
When an exception occurs in the try block, the catch clauses are checked sequentially. A catch clause catches the exception if the thrown object is an instance of the specified type in the catch clause.
When multiple statements in a single try block throw different exceptions, different catch blocks must be written, one for each type of exception. On the other hand, each statement that might throw exceptions can be put into different try-catch blocks. Alternatively, a single catch block can be defined as its parameter type, which is a super-class of all the exceptions to be handled. In some way, we have to identify particular exceptions and catch them within the catch block. It can be achieved by using the instance of the operator, as shown in the following example:catch (Exception e) { if(e instance of ArithmeticException){ ............. } else { if (e instance of NumberFormatException){ ............. } } else ........... ........... }If a single statement throws multiple exceptions, it is better to have multiple catch blocks associated with the try block.
The order of catch blocks is very important when there are multiple catch blocks.
Nested try statements
The try statement can be nested. That is, one try statement can be placed inside the block of another try. Each time a try statement is entered, the context of that exception is pushed on the stack. If an inner try statement does not have a catch handler for a particular exception, the stack is unwound, and the catch handlers belonging to the next try statement are inspected for a match. It continues until one of the catch statements succeeds or until all the nested try statements are exhausted. If no catch statement matches, then the Java run-time system will handle the exception. In Program, a pair of nested try statements have been used.
Program Using nested try-catch statements.
public class Divide { public static void main(String[] args){ System.out.println("\n Program Execution starts here\n"); int a, b, c; try{ a = Integer.parselnt (args [0]); b = Integer.parselnt (args [1]); try{ c = a/b; System.out.println( a +"I"+ b +"="+ c); } catch(ArithmeticException e){ System.out.println("Second Argument Should not be Zero"); } } catch(NumberFormatException e){ System.out.println("Arguments passed should be valid Numbers"); } catch(ArraylndexOutOfBoundsException e){ System.out.println("Pass Proper Arguments"); } System.out.println("\n Program Execution Completes here"); } }The keyword throw
An exception can be caught if it is identified or, in other words, thrown. Exceptions can be thrown by the Java run-time system for the code that has been written. It can also be achieved by using the throw statement explicitly.
This statement starts with the keyword throw, followed by a single argument. The argument must be an object instantiated from the Throwable class or its subclass. The syntax for using the throw statement is the following:throw <Exception object>In a specific case where an instance of ‘Exception object’ is to be thrown, it takes the following form:
throw new <Exception object>Usually the above statement is used to pass a string argument along with the exceptional object, so that the string can be displayed when the exception is handled.
Example
throw new IndexOutOfBoundsException ("Index out of range");The throw statement is generally written with a conditional statement such as an if statement and switch statement. It is more useful when it comes to throwing user-defined exceptions that the Java run-time system cannot recognize.
The program illustrates the use of conditional statements:Program using throw keyword.
public class Main { public static void main (String args []) throws Exception { int number1 = 15, number2 = 10; if(number1 > number2)// Conditional statement. throw new Exception("number1 is 15"); else System.out.println("number2 is 15"); } }The output of Program is
Exception in thread "main" java.Exception: number1 is 15 at Test Throw.main (Test Throw.java:8)In the program, the keyword throw is used to throw an exception with the message. With throw, the programmer is allowed to throw the exception and the system prints the messages and terminates the program.