Chapter-5
EXCEPTION HANDLING
Introduction to Exception Handling:
• An Exception is an unwanted or unexpected event that occurs during the execution of a
program (i.e., at runtime) and disrupts the normal flow of the program’s instructions.
• It occurs when something unexpected happens, like accessing an invalid index, dividing by
zero, or trying to open a file that does not exist.
• Java provides a way to handle such errors using exception handling.
• A Java exception is an object that describes an exceptional (that is, error) condition that has
occurred in a piece of code. When an exceptional condition arises, an object representing that
exception is created and thrown in the method that caused the error.
• Exceptions can be generated by the Java run-time system, or they can be manually generated
by our code.
• Exceptions can be generated by the Java run-time system, or they can be manually generated
by our code.
• Exceptions thrown by Java relate to fundamental errors that violate the rules of the Java
language or the constraints of the Java execution environment.
• Manually generated exceptions are typically used to report some error condition to the caller
of a method.
• Java exception handling is managed via five keywords: try, catch, throw, throws, and
finally
Keywords in Exception Handling:
• try block contains program statements that are to be to monitored for exceptions
– If an exception occurs within the try block, it is thrown
• catch block contain statements that catch this exception and handle it in some
rational manner – System-generated exceptions are automatically thrown by the
Java runtime system.
• throw is used to manually throw an exception.
• throws clause is used to specify any exception that is thrown out of a method.
• finally block contains code that absolutely must be executed after a try block
completes.
The general form of an exception-handling block :
try{
// block of code to monitor for errors
}
catch (ExceptionType1 exOb) {
// exception handler for ExceptionType1
}
catch (ExceptionType2 exOb) {
// exception handler for ExceptionType2
}
finally {
// block of code to be executed after try block ends
}
Exception Types:
• All exception types are subclasses of the
built-in class Throwable
• Below Throwable are two subclasses that
partition exceptions into two branches
• Exception class: used for exceptional
conditions that user programs should catch
• RuntimeException etc are subclasses
of Exception.
• Error class: used by the Java runtime
system to indicate errors having to do
with the run-time environment (eg
Stack overflow)
• Every Exception type is basically an object
belonging to class Exception
Uncaught Exception:
• Before you learn how to handle exceptions in your program, it is useful to see what
happens when you don’t handle them. This small program includes an expression that
intentionally causes a divide-by-zero error:
class ExcDemo {
public static void main(String args[]) {
int d = 0;
int a = 42 / d;
}
}
• When the Java run-time system detects the attempt to divide by zero, it constructs a new
exception object and then throws this exception. This causes the execution of Exc0 to
stop, because once an exception has been thrown, it must be caught by an exception
handler and dealt with immediately.
• Any exception that is not caught by your program will ultimately be processed by the
default handler and it displays a string describing the exception, prints a stack trace from
the point at which the exception occurred, and terminates the program.
java.lang.ArithmeticException: / by zero
at Exc0.main(Exc0.java:4)
Using try and Catch:
• Although the default exception handler provided by the Java run-time system is useful for
debugging, you will usually want to handle an exception yourself. Doing so provides two
benefits.
• First, it allows you to fix the error.
• Second, it prevents the program from automatically terminating.
• To guard against and handle a run-time error, simply enclose the code that you want to
monitor inside a try block.
• Immediately following the try block, include a catch clause that specifies the exception
type that you wish to catch.
• To illustrate how easily this can be done, the following program includes a try block and a
catch clause that processes the ArithmeticException generated by the division-by-zero
error:
Example try and Catch:
class Exc2 {
public static void main(String args[]) {
int d, a;
try { // monitor a block of code.
d = 0;
a = 42 / d;
System.out.println("This will not be printed.");
} catch (ArithmeticException e) { // catch divide-by-zero error
System.out.println("Division by zero.");
} finally { // Finally Block
System.out.println("This is the finally block.");
}
System.out.println("After catch statement.");
}
}
• Notice that the call to println( ) inside the try block is never executed. Once an exception
is thrown, program control transfers out of the try block into the catch block.
Multiple catch statements:
• You can catch different types of exceptions separately.
• Useful for handling multiple error types differently.
• Use when more than one exception could be raised by a single piece of code
Example:
class MultiCatchExample {
public static void main(String args[]) {
try {
int a = 10, b = 0;
int result = a / b; // divide-by-zero error
int[] arr = {1, 2, 3};
System.out.println(arr[5]); // array index out of
bounds
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero.");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Array index is out of bounds.");
}
System.out.println(“After try/Catch Blocks.");
}
Catching Subclass Exceptions:
• There is one important point about multiple catch statements that relates to subclasses.
A catch clause for a superclass will also match any of its subclasses.
• For example, since the superclass of all exceptions is Throwable, to catch all possible
exceptions, catch Throwable.
• If you want to catch exceptions of both a superclass type and a subclass type, put the subclass
first in the catch sequence.
• If you don’t, then the superclass catch will also catch all derived classes.
• This rule is self-enforcing because putting the superclass first causes unreachable code to be
created, since the subclass catch clause can never execute. In Java, unreachable code is an error.
// This code will not compile
try {
String s = null;
System.out.println(s.length());
} catch (Exception e) {
System.out.println("Caught Exception");
} catch (NullPointerException e) {
System.out.println("Caught NullPointerException");
Example: Catching Subclass Exception First
class SubclassCatch {
public static void main(String args[]) {
try {
String s = null;
System.out.println(s.length()); // This throws NullPointerException
} catch (NullPointerException e) {
System.out.println("Caught NullPointerException");
} catch (Exception e) {
System.out.println("Caught Exception");
}
}
}
Throwing an Exceptions:
• So far, you have only been catching exceptions that are thrown by the Java run-time
system. However, it is possible for your program to throw an exception explicitly, using
the throw statement.
• The general form: throw ThrowableInstance;
• flow of execution stops immediately after the throw statement
• nearest enclosing try block is inspected to see if it has a catch statement that matches the
type of exception and control is transferred to that statement
• No match: next enclosing try statement is inspected, and so on
• no matching catch found in any block: default exception handler halts the program and
prints the stack trace
Example: throw
class ThrowDemo {
static void demoproc() {
try {
throw new NullPointerException("demo");
} catch (NullPointerException e) {
System.out.println("Caught inside demoproc.");
throw e; // rethrow the exception
}
}
public static void main(String args[]) {
try {
demoproc();
} catch (NullPointerException e) {
System.out.println("Recaught: " + e);
}
} Output:
} Caught inside demoproc.
Recaught: java.lang.NullPointerException:
demo
Throwing an Exceptions:
• If a method is capable of causing an exception that it does not handle, it must specify this
behavior so that callers of the method can guard themselves against that exception.
• By including a throws clause in the method’s declaration. A throws clause lists the types of
exceptions that a method might throw.
• This is necessary for all exceptions, except those of type Error or RuntimeException, or any of
their subclasses.
• The general form of a method declaration that includes a throws clause:
type method-name(parameter-list) throws exception-list {
// body of method
Here, exception-list is a comma-separated list of the exceptions that a method can
throw.
Example: throws
class ThrowsDemo {
static void throwOne() throws IllegalAccessException {
System.out.println("Inside throwOne.");
throw new IllegalAccessException("demo");
}
public static void main(String args[]) {
try {
throwOne();
} catch (IllegalAccessException e) {
System.out.println("Caught " + e);
}
} Output:
} Inside throwOne.
Caught java.lang.IllegalAccessException:
demo
A Closer Look at Throwable:
Up to this point, we have been catching exceptions, but we haven’t been doing anything
with the exception object itself. As the preceding examples all show, a catch clause specifies
an exception type and a parameter. The parameter receives the exception object. Since all
exceptions are subclasses of Throwable, all exceptions support the methods defined
by Throwable. Several commonly used ones are shown in the below Table.
Of the methods defined by Throwable, two of the most interesting are
printStackTrace() and toString(). You can display the standard error message plus a record
of the method calls that lead up to the exception by calling printStackTrace( ). You can
use toString( ) to retrieve the standard error message. The toString( ) method is also called
when an exception is used as an argument to println( ).
Java’s Built-in Exceptions:
Java’s Built-in Exceptions:
Creating Exception Subclasses:
• Although Java’s built-in exceptions handle most common errors, you will probably want
to create your own exception types to handle situations specific to your applications. This
is quite easy to do: just define a subclass of Exception (which is, of course, a subclass of
Throwable). Your subclasses don’t need to actually implement anything—it is their
existence in the type system that allows you to use them as exceptions.
• The Exception class does not define any methods of its own. It does, of course, inherit
those methods provided by Throwable. Thus, all exceptions, including those that you
create, have the methods defined by Throwable available to them.
Example:
class AgeException extends Exception {
String msg;
AgeException(String message) {
msg = message; }
public String toString() {
return "AgeException: " + msg; }
}
}
class TestAge {
public static void main(String args[]) {
int age = 16;
try {
if (age < 18) {
throw new AgeException("Age is less than 18. Not allowed to vote.");
} else {
System.out.println("You are allowed to vote.");
}
} catch (AgeException e)
System.out.println("Caught: " + e);
}
Caught: AgeException: Age is less than 18. Not
allowed to vote.