Exception Handling
1. The Java programming language uses exceptions to handle errors and other exceptional
events.
2. An exception is an abnormal condition that arises in a code sequence at run time.
3. In other words, an exception is a run-time error.
4. In Java, an exception is an object.
5. Exceptions can be generated by
- the Java run-time system, or
- they can be manually generated by our code.
6. Java exception handling is managed via five keywords: try, catch, throw, throws, and
finally.
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
// cleanup code
}
Points:
1) Each try statement requires at least one catch or a finally clause..
2) Multiple catch statements can be associated with a single try block
3) finally block is optional. But, finally block always executes after try/catch
blockcompletes.
Exception Types / Exception Hierarchy
➢ All exceptions are subclasses of Throwable class.
➢ Throwable class has two sub-types: 1) Error and 2) Exception
➢ Exception class has a subclass called – RuntimeException
➢ User-defined exceptions can be created by extending Exception class.
Exception Types (Built-in Exceptions)
There are two types of exceptions:
1) Checked exceptions
2) Unchecked exceptions
1) Checked Exceptions
➢ These are exceptional conditions that a well-written application should anticipate and
recover from.
➢ Checked exceptions must follow the requirement - Catch or declare the exception
using throws.
Ex: java.io.FileNotFoundException.
➢ All exceptions are checked exceptions, except for those indicated
by Error, RuntimeException, and their subclasses i.e The classes
that directly inherit the Throwable class except RuntimeException
and Error are known as checked exceptions. For example,
IOException, SQLException, etc.
➢ Checked exceptions are checked at compile-time.
CloneNotSupportedException Attempt to clone an object that does not implement
the Cloneable interface.
IllegalAccessException Access to a class is denied.
InstantiationException Attempt to create an object of an abstract class or
interface.
InterruptedException One thread has been interrupted by another thread.
NoSuchFieldException A requested field does not exist.
NoSuchMethodException A requested method does not exist.
ReflectiveOperationException Superclass of reflection-related exceptions
2) Unchecked Exceptions
➢ Errors and runtime exceptions are collectively known as unchecked exceptions.
➢ Unchecked exceptions need not follow the requirement - Catch or declare the
exception using throws.
Error:
➢ These are exceptional conditions that are external to the application, and that the
application usually cannot anticipate or recover from.
➢ Error is irrecoverable. Some example of errors are OutOfMemoryError,
VirtualMachineError, AssertionError etc.
Ex: An application successfully opens a file for input, but is unable to read the file because
of a hardware or system malfunction.
Runtime Exception:
➢ The classes that inherit the RuntimeException are known as unchecked
exceptions. For example, ArithmeticException, NullPointerException,
ArrayIndexOutOfBoundsException, etc.
➢ Unchecked exceptions are not checked at compile-time, but they are checked at
runtime.
➢ These are exceptional conditions that are internal to the application, and that the
application usually cannot anticipate or recover from.
➢ These usually indicate programming bugs, such as logic errors or improper use of an
API.
Ex: NullPointerException
ArithmeticException Arithmetic error, such as divide-by-zero.
ArrayIndexOutOfBoundsException Array index is out-of-bounds.
ArrayStoreException Assignment to an array element of an incompatible type
ClassCastException Invalid cast.
IllegalArgumentException Illegal argument used to invoke a method.
IllegalMonitorStateException Illegal monitor operation, such as waiting on an unlocked
thread
IllegalStateException Environment or application is in incorrect state.
IllegalThreadStateException Requested operation not compatible with current thread
state.
IndexOutOfBoundsException Some type of index is out-of-bounds.
NegativeArraySizeException Array created with a negative size.
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.
Methods in Throwable
Throwable fillInStackTrace( ) Returns a Throwable object that contains a completed
stack trace. This object can be rethrown.
String getMessage( ) Returns a description of the exception.
void printStackTrace( ) Displays the stack trace.
String toString( ) Returns a String object containing a description of the
exception. This method is called by println( ) when
outputting a Throwable object.
Propagating Uncaught Exceptions – call stack
class ExceptionTest1 {
public static void main (String [] args)
{doStuff();
}
static void doStuff()
{
doMoreStuff();
}
static void doMoreStuff()
➔ Unhandled or uncaught
exceptions will be handled by
default handler provided by
{ JVM.
int x = 5/0;
} Call stack:
}
Call stack is the sequence of methods
which led to the error
Output:
Exception in thread "main" java.lang.ArithmeticException: / by
zeroat ExceptionTest1.doMoreStuff(ExceptionTest1.java:11)
at ExceptionTest1.doStuff(ExceptionTest1.java:7)
at ExceptionTest1.main(ExceptionTest1.java:3)
Example for Exception Handling using try/catch/finally
class ExcExample{
public static void main(String args[])
{try {
int a = args.length;
System.out.println("a = " +
a);int b = 42 / a;
int c[] = { 1
};c[42] = 99;
}
catch(ArithmeticException e) {
System.out.println("Divide by 0: " +
e);
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("Array index oob: " +
e);
}
finall
y
{ System.out.println("In finally block.");
}
System.out.println("After try/catch/finally blocks.");
}
}
Nested Try
➢ A try statement can be inside the block of another try. This is called as Nested Try
statement.
➢ If an inner try statement does not have a catch handler for a particular exception, the
next try statement’s catch handlers are inspected for a match.
➢ This continues until one of the catch statements succeeds, or until all of the nested try
statements are exhausted.
➢ If no catch statement matches, then the Java run-time system will handle the exception.
// An example of nested try statements.
public class NestedTryBlock{
public static void main(String args[]){
//outer try block
try{
//inner try block 1
try{
System.out.println("going to divide by 0");
int b =39/0;
}
//catch block of inner try block 1
catch(ArithmeticException e)
{
System.out.println(e);
}
//inner try block 2
try{
int a[]=new int[5];
//assigning the value out of array bounds
a[5]=4;
}
//catch block of inner try block 2
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println(e);
}
System.out.println("other statement");
}
//catch block of outer try block
catch(Exception e)
{
System.out.println("handled the exception (outer catch)");
}
System.out.println("normal flow..");
}
}
Output:
When any try block does not have a catch block for a particular exception, then the catch block of the outer
(parent) try block are checked for that exception, and if it matches, the catch block of outer try block is
executed.
If none of the catch block specified in the code is unable to handle the exception, then the Java runtime
system will handle the exception. Then it displays the system generated message for that exception.
class NestTry {
public static void main(String args[])
{try {
int a = args.length;
/* If no command-line args are present, the following statement
willgenerate a divide-by-zero exception. */
int b = 42 / a;
System.out.println("a = " +
a);
try { // nested try block
/* If one command-line arg is used, then a divide-by-zero
exception will be generated by the following code. */
if(a==1)
a = a/(a-a); // division by zero
/* If two command-line args are used,then generate an out-of-
bounds exception. */
if(a==2) {
int c[] = { 1 };
c[42] = 99; // generate an out-of-bounds exception
}
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("Array index out-of-bounds: " +
e);
}
}
catch(ArithmeticException e) {
System.out.println("Divide by 0: " +
e);
}
}
}
throw
➢ It is possible for the program to throw an exception explicitly, using the throw
statement.
➢ The general form of throw is shown here:
➢ throw ThrowableInstance;
➢ Here, ThrowableInstance must be an object of type Throwable or a
subclass of Throwable.
➢ The flow of execution stops immediately after the throw statement; any
subsequent statements are not executed.
public class TestThrow1 {
//function to check if person is eligible to vote or not
public static void validate(int age) {
if(age<18) {
//throw Arithmetic exception if not eligible to vote
throw new ArithmeticException("Person is not eligible to vote");
}
else {
System.out.println("Person is eligible to vote!!");
}
}
//main method
public static void main(String args[]){
//calling the function
validate(13);
System.out.println("rest of the code...");
}
}
Output:
// Demonstrate throw.
class ThrowDemo {
static void demoproc() {
try {
throw new NullPointerException("demo");
} catch(NullPointerException e) {
System.out.println("Caught inside
demoproc.");
}
}
public static void main(String
args[]) { try {
demoproc();
} catch(NullPointerException e) {
System.out.println("Recaught:
" + e);
}
}}
throws clause
If a method is causing an exception but it does not handle then it must specify
it’s behavior so that callers of the method can guard themselves against that
exception.
throws clause is used to specify it’s behavior.
type method-name(parameter-list) throws exception-list
{
// body of method
}
//Example for throws demo
import java.io.IOException;
class Testthrows1{
void m()throws IOException{
throw new IOException("device error");//checked exception
}
void n()throws IOException{
m();
}
void p(){
try{
n();
}catch(Exception e){System.out.println("exception handled");}
}
public static void main(String args[]){
Testthrows1 obj=new Testthrows1();
obj.p();
System.out.println("normal flow...");
}
}
Output:
exception handled
normal flow...
Another ex:
class ThrowsDemo {
static void demoproc() throws
IllegalAccessException{ throw new
IllegalAccessException("demo");
}
public static void main(String args[]) throws IllegalAccessException
{
demoproc();
}
}
throw vs throws
throw throws
Java throw keyword is used to Java throws keyword is used to
explicitly throw an exception. declare an exception
Checked exception cannot be Checked exception can be
propagated using throw only. propagated with throws.
Throw is followed by an instance. Throws is followed by class.
Throw is used within the method. Throws is used with the method
signature
You cannot throw multiple You can declare multiple
exceptions.
exceptions e.g. public void
method()throws
IOException,SQLException
finally
1) finally creates a block of code that will be executed after a try
/catch block has completed and before the code following the
try/catch block.
2) The finally block will execute whether or not an exception is thrown.
3) If an exception is thrown, the finally block will execute even if no catch
statement matches the exception.
4) Any time a method is about to return to the caller from inside a try/catch
block, via an uncaught exception or an explicit return statement, the
finally clause is also executed just before the method returns.
// Demonstrate finally
class FinallyDemo {
// Throw an exception out of the
method. static void procA() {
try {
System.out.println("inside
procA"); throw new
} RuntimeException("demo");
finall
y{
} System.out.println("procA's finally");
}
// Return from within a try
block. static void procB() {
try {
System.out.println("inside
procB"); return;
} Output:
finall inside procA
y { System.out.println("procB's finally"); procA's finally
Exception caught
inside procB
} procB's finally
} inside procC
procC's finally
// Execute a try block
normally. static void
procC() {
try {
System.out.println("inside
}
finall
y{
procC");
}
}
System.out.println("procC's
finally");
public static void main(String
args[]) { try
{
procA();
}
catch (Exception e) {
System.out.println("Exception caught");
}
procB();
procC();
}
}
Custom / User-defined Exception (Creating our OwnException
Subclasses)
To create a custom exception, program just need to define a class that extends Exception
class.
// This program creates a custom exception type.
Import java.lang.Exception;
class MyException extends Exception
{ MyException(String msg)
{ super(msg);}
}
class CustomExcDemo
{
public static void main(String args[])
{
int x=5, y=1000;
try {
float z = (float)x/(float)y;
if (z<0.01)
{ throw new MyException(“too small number”); }
}
catch (MyException e) {
System.out.println("Caught my exception " + e);
System.out.println(“my exception " + e.getMessage());
}
}
}