- Redirecting and Rethrowing Exceptions in Java
- Redirecting exceptions using throws
- Rethrowing an exception
- You’ll also like:
- Java Catch Multiple Exceptions, Rethrow Exception
- Java catch multiple exceptions
- Java rethrow exception
- Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking
- Rethrowing Exceptions with More Inclusive Type Checking
Redirecting and Rethrowing Exceptions in Java
We’ll be covering the following topics in this tutorial:
Redirecting exceptions using throws
Recall that the code capable of throwing an exception is kept in the try block and the exceptions are caught in the catch block. When there is no appropriate catch block to handle the (checked) exception that was thrown by an object, the compiler does not compile the program. To overcome this, Java allows the programmer to redirect exceptions that have been raised up the call stack, by using the keyword throws. Thus, an exception thrown by a method can be handled either in the method itself or passed to a different method in the call stack.
To pass exceptions up to the call stack, the method must be declared with a throws clause.
All the exceptions thrown by a method can be declared with a single throws clause; the clause consists of the keyword throws followed by a comma-separated list of all the exceptions, as shown below:
Void RedirectExMethod( ) throws Exception_A, Exception B, Exception C
Program illustrates two methods redirecting an exception Exception from the method
throwing it, that is, ConvertAndDivide, to the calling method, main.
Program Redirecting exceptions.
public class Divide < public static void main(String[] args) < System.out.println("\n Program Execution starts here\n"); try < convertAndDivide ( args[0],args[1]); >catch(Exception e) < System.out.println (e.getMessage () +"\n"); e.printStackTrace (); >System.out.println("\n Program Execution Completes here"); > static void convertAndDivide (String s 1,String s2) throwsException < int a, b, c; a = Integer.parselnt (s1); b = Integer.parselnt (s2); c = divide (a, b); System.out.println( a + "/" + b + "=" + C ); >static int divide(int x, int y) throws Exception < if (y==0) < throw new Exception("Second Argument is Zero . "); >return x/y; > >
The output of Program is the following:
Program Execution starts here
Program Execution Completes here
Program Execution starts here a
java.lang.NumberFormatException: a at java.lang.lnteger.parse Int (1nteger.java:426) at java.lang.lnteger.parsel Int (1ntege r.java:476) at Divide.convertAndDivide (Divide.java:26) at Divide.main (Divide,java:9)
Program Execution Completes here
The method getMessage() in Program just prints the message that is given at the time of the throw statement. If no message is given, then the data value that is responsible for the exception is shown; printStackTrace() prints the all the names of the methods that are called in generating the exception. The method names are printed in the reverse order of their call.
While defining exception handlers, it is instructive to take into account the scope of a method. The scope of the exception-handling mechanism is not limited to the exceptions that can be thrown by the code written into the method; it extends to the methods that called the method in which the exception is thrown. That is, the scope also includes exceptions thrown by methods called by that method and so on.
Rethrowing an exception
An exception that is caught in the try block can be thrown once again and can be handled. The try block just above the rethrow statement will catch the rethrown object. If there is no try block just above the rethrow statement then the method containing the rethrow statement handles it. To propagate an exception, the catch block can choose to rethrow the exception by using the throw statement. Note that there is no special syntax for rethrowing. Program illustrates how an exception can be rethrown .
Program Rethrowing exceptions.
public class Divide < public static void main(String[] args) < int a, b, c; try < a = Integer.parselnt (args [0]); b = Integer.parselnt (args [l]); try < c = a/b; System.out.println ( a + "I" + b + "=" + c); >catch (ArithmeticException e) < System.out.println ("Second Argument Should not be Zero"); System.out.println ("Rethrowing the object again"); throw 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"); > >
Often first-time readers may get confused about the use of the three keywords: throw, throws and Throwable. It is therefore useful to dwell on the three concepts together in order to clarify their meaning.
Throwable is a class. Though the Throwable class is derived from the java.lang.Object class in the Java class library, Throwable is the super-class of all classes that handle exceptions.
The keyword throw is a statement that throws an exception. Note that an exception can be thrown either by the throw statement or when an error occurs during the execution of any other statement.
The keyword throws is a clause specified in the method definition which indicates that the method throws the exceptions mentioned after the keyword throws, which are handled in the called methods.
You’ll also like:
Java Catch Multiple Exceptions, Rethrow Exception
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
In Java 7, catch block has been improved to handle multiple exceptions in a single catch block. If you are catching multiple exceptions and they have similar code, then using this feature will reduce code duplication. Let’s understand java catch multiple exceptions feature with an example.
Java catch multiple exceptions
Before Java 7, we used to catch multiple exceptions one by one as shown below.
catch(IOException | SQLException ex)
If a catch block handles multiple exceptions, you can separate them using a pipe (|) and in this case, exception parameter (ex) is final, so you can’t change it. The byte code generated by this feature is smaller and reduce code redundancy.
Java rethrow exception
Another improvement is done in Compiler analysis of rethrown exceptions. Java rethrow exception allows you to specify more specific exception types in the throws clause of a method declaration. Let’s see this with a small example:
package com.journaldev.util; public class Java7MultipleExceptions < public static void main(String[] args) < try< rethrow("abc"); >catch(FirstException | SecondException | ThirdException e) < //below assignment will throw compile time exception since e is final //e = new Exception(); System.out.println(e.getMessage()); >> static void rethrow(String s) throws FirstException, SecondException, ThirdException < try < if (s.equals("First")) throw new FirstException("First"); else if (s.equals("Second")) throw new SecondException("Second"); else throw new ThirdException("Third"); >catch (Exception e) < //below assignment disables the improved rethrow exception type checking feature of Java 7 // e=new ThirdException(); throw e; >> static class FirstException extends Exception < public FirstException(String msg) < super(msg); >> static class SecondException extends Exception < public SecondException(String msg) < super(msg); >> static class ThirdException extends Exception < public ThirdException(String msg) < super(msg); >> >
As you can see that in rethrow method, catch block is catching Exception but it’s not part of throws clause. Java 7 compiler analyze the complete try block to check what types of exceptions are thrown and then rethrown from the catch block. Note that this analysis is disabled if you change the catch block argument. Further Reading: Exception Handling in Java.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases. Learn more about us
Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking
In Java SE 7 and later, a single catch block can handle more than one type of exception. This feature can reduce code duplication and lessen the temptation to catch an overly broad exception.
Consider the following example, which contains duplicate code in each of the catch blocks:
catch (IOException ex) < logger.log(ex); throw ex; >catch (SQLException ex)
In releases prior to Java SE 7, it is difficult to create a common method to eliminate the duplicated code because the variable ex has different types.
The following example, which is valid in Java SE 7 and later, eliminates the duplicated code:
catch (IOException|SQLException ex)
The catch clause specifies the types of exceptions that the block can handle, and each exception type is separated with a vertical bar ( | ).
Note: If a catch block handles more than one exception type, then the catch parameter is implicitly final . In this example, the catch parameter ex is final and therefore you cannot assign any values to it within the catch block.
Bytecode generated by compiling a catch block that handles multiple exception types will be smaller (and thus superior) than compiling many catch blocks that handle only one exception type each. A catch block that handles multiple exception types creates no duplication in the bytecode generated by the compiler; the bytecode has no replication of exception handlers.
Rethrowing Exceptions with More Inclusive Type Checking
The Java SE 7 compiler performs more precise analysis of rethrown exceptions than earlier releases of Java SE. This enables you to specify more specific exception types in the throws clause of a method declaration.
Consider the following example:
static class FirstException extends Exception < >static class SecondException extends Exception < >public void rethrowException(String exceptionName) throws Exception < try < if (exceptionName.equals("First")) < throw new FirstException(); >else < throw new SecondException(); >> catch (Exception e) < throw e; >>
This examples’s try block could throw either FirstException or SecondException . Suppose you want to specify these exception types in the throws clause of the rethrowException method declaration. In releases prior to Java SE 7, you cannot do so. Because the exception parameter of the catch clause, e , is type Exception , and the catch block rethrows the exception parameter e , you can only specify the exception type Exception in the throws clause of the rethrowException method declaration.
However, in Java SE 7, you can specify the exception types FirstException and SecondException in the throws clause in the rethrowException method declaration. The Java SE 7 compiler can determine that the exception thrown by the statement throw e must have come from the try block, and the only exceptions thrown by the try block can be FirstException and SecondException . Even though the exception parameter of the catch clause, e , is type Exception , the compiler can determine that it is an instance of either FirstException or SecondException :
public void rethrowException(String exceptionName) throws FirstException, SecondException < try < // . >catch (Exception e) < throw e; >>
This analysis is disabled if the catch parameter is assigned to another value in the catch block. However, if the catch parameter is assigned to another value, you must specify the exception type Exception in the throws clause of the method declaration.
In detail, in Java SE 7 and later, when you declare one or more exception types in a catch clause, and rethrow the exception handled by this catch block, the compiler verifies that the type of the rethrown exception meets the following conditions:
- The try block is able to throw it.
- There are no other preceding catch blocks that can handle it.
- It is a subtype or supertype of one of the catch clause’s exception parameters.
The Java SE 7 compiler allows you to specify the exception types FirstException and SecondException in the throws clause in the rethrowException method declaration because you can rethrow an exception that is a supertype of any of the types declared in the throws .
In releases prior to Java SE 7, you cannot throw an exception that is a supertype of one of the catch clause’s exception parameters. A compiler from a release prior to Java SE 7 generates the error, «unreported exception Exception ; must be caught or declared to be thrown» at the statement throw e . The compiler checks if the type of the exception thrown is assignable to any of the types declared in the throws clause of the rethrowException method declaration. However, the type of the catch parameter e is Exception , which is a supertype, not a subtype, of FirstException and SecondException . catch parameter, and the exception handled by this catch block is not reassigned, then these exception types are implicitly final . You may explicitly declare these exception types as final ; however this is not necessary:
catch (final IOException|SQLException ex)
Exception types that are not final (in particular, catch blocks in which the handled exception is reassigned) affect the features discussed on this page as follows:
- The compiler generates an error for catch blocks that handles more than one exception type.
- The compiler will not perform the more inclusive type checking for rethrown exceptions.