Exception Handling
Exceptions
Definition:
◦ An exception is an event that disrupts the normal flow of a program.
◦ Occurs during runtime when an unexpected situation happens.
Examples:
◦ Division by zero → ArithmeticException
◦ File not found → FileNotFoundException
◦ Null reference access → NullPointerException
Why handle exceptions?
◦ To prevent program crashes.
◦ To allow recovery or graceful termination.
Errors vs Exceptions
Aspect Errors Exceptions
Serious problems, not intended to be
Definition Conditions that can be anticipated and handled
handled by the program
Examples OutOfMemoryError, StackOverflowError IOException, NumberFormatException
Recovery Typically not possible Possible through handling
Benefits of Exception Handling
1. Improves program reliability.
2. Separates error-handling logic from normal code.
3. Allows graceful recovery.
4. Supports debugging by providing stack traces.
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
[Link]("Cannot divide by zero!");
}
Types of Exceptions in Java
Checked Exceptions – Checked at compile-time.
◦ The compiler forces the programmer to either handle them using try-catch blocks or declare them using the
throws keyword.
◦ Typically represent conditions outside the program’s control (I/O errors, database issues, etc.).
◦ Examples: IOException, SQLException, ClassNotFoundException, FileNotFoundException.
Unchecked Exceptions – Occur at runtime, not checked at compile-time.
◦ They usually indicate programming errors, such as logical mistakes or improper use of APIs.
◦ The programmer is not forced to handle them explicitly.
◦ Example: NullPointerException, ArrayIndexOutOfBoundsException.
Errors – Serious issues, not handled in normal programs.
◦ They are not exceptions but fall under the broader category of Throwable.
◦ Examples: OutOfMemoryError, StackOverflowError, VirtualMachineError.
Java Exception Hierarchy
All exception types are subclasses of the
built-in class Throwable.
Immediately below Throwable has two
subclasses that partition exceptions into two
distinct.
One branch is Exception.
Other branch is Error
Top-level class: [Link]
◦ Error → serious system errors.
◦ Exception → recoverable situations.
◦ Checked → must be handled.
◦ Unchecked (RuntimeException) → programmer errors.
Exception Handling
1. Java exception handling is managed via five keywords:
try, catch, throw, throws, and finally.
2. Program statements that you want to monitor for exceptions are contained within a try block.
3. If an exception occurs within the try block, it is thrown.
4. Your code can catch this exception using catch and handle it in some rational manner.
5. System generated exceptions are automatically thrown by the Java run-time system.
6. To manually throw an exception, use the keyword throw.
7. Any exception that is thrown out of a method must be specified as such by a throws clause.
8. Any code that absolutely must be executed after a try block completes is put in a finally
block.
Exception vs Error in Java
Aspect Exception Error
Represents conditions that a program should Represents serious problems that usually cannot be
Definition
anticipate and handle. handled by the program.
Branch of
Exception Error
Throwable
- Checked Exceptions (e.g., IOException,
- JVM Errors (e.g., VirtualMachineError) - System-
SQLException) - Unchecked Exceptions
Sub-types level Errors (e.g., OutOfMemoryError,
(RuntimeException and its subclasses, e.g.,
StackOverflowError)
NullPointerException, ArithmeticException)
Can and should be handled using try-catch-finally Not recommended to handle. Usually beyond
Handling
or declared using throws. programmer’s control.
Mostly application-level issues, external factors JVM-level or system-level failures, resource
Cause
like I/O failures, or coding mistakes. exhaustion.
Often recoverable; program can continue
Recoverability Rarely recoverable; program usually terminates.
execution after handling.
IOException, SQLException,
OutOfMemoryError, StackOverflowError,
Examples NullPointerException,
VirtualMachineError
ArrayIndexOutOfBoundsException
Uncaught Exceptions
When the Java run-time system detects the attempt to divide by zero, it
What happen if we do not handle exceptions? constructs a new exception object and then throws this exception.
class Abc {
This causes the execution of Abc to stop, because once an exception has
public static void main ( String args[ ] ) been thrown, it must be caught by an exception handler and dealt with
{
immediately.
int i = 0;
int j = 34 / i ; Any exception that is not caught by the program, will be
} processed by the default handler provided by java run time system.
} The default handler displays a string describing the exception, prints a
stack trace from the point at which the exception occurred, and
terminates the program.
This program includes an expression that
causes a divide-by-zero error. [Link]: / by zero at [Link]([Link]: 4)
Basic Exception Handling: try–catch
class Abc {
try { public static void main ( String args[ ] ) {
try{
// code that may throw an exception int i = 0;
} catch (ExceptionType e) { int j = 34 / i ;
} catch (ArithmeticException e) {
// handle the exception [Link] (“Division
by zero.”)
} }
[Link](“After catch
statement.”)
}
}
Output:
Division by zero
After catch statement
*Note
A try and its catch statement form a unit.
The scope of the catch clause is restricted to those statements specified by the immediately preceding try
statement.
A catch statement cannot catch an exception thrown by another try statement.
Except in the case of nested try statements
Example
import [Link];
public class ExceptionDemo {
public static void main(String[] args) {
int a =0, b=0, c=0;
Random r = new Random ();
for (int i =0; i<32000; i++){
try{
b = [Link]();
c = [Link]();
int k = (b – c) ;
a = 123456 / k;
} catch (ArithmeticException e){
[Link] (“ Division by zero.”);
a = 0;
}
}
}
}
Displaying a Description of an Exception
Every exception object in Java has methods that can be used to get details
about the exception.
The most common are:
◦ getMessage() → returns a description of the exception.
◦ toString() → returns the exception type + description.
◦ printStackTrace() → prints the complete stack trace.
Example
public class ExceptionDescriptionDemo {
public static void main(String[] args) { Using getMessage(): / by zero
try {
int num = 10 / 0; // causes ArithmeticException Using toString(): [Link]: / by
} catch (ArithmeticException e) { zero
[Link]("Using getMessage(): " + [Link]());
[Link]("Using toString(): " + [Link]()); Using printStackTrace():
[Link]("Using printStackTrace(): "); [Link]: / by zero
[Link](); at
} [Link](ExceptionDescription
[Link]("Program continues..."); [Link])
} Program continues...
}
Multiple catch Blocks
In some cases, more than one exception could be raised by a single piece of code.
To handle this type of situation, you can specify two or more catch clauses, each catching a
different type of exception.
When an exception is thrown, each catch statement is inspected in order, and the first one
whose type matches that of the exception is executed.
After one catch statement executes, the others are bypassed, and execution continues after the
try / catch block.
Example
public class MultipleCatchDemo {
public static void main(String[] args) {
try {
int arr[] = new int[5];
arr[10] = 100; // ArrayIndexOutOfBoundsException
int result = 10 / 0; // ArithmeticException
}
catch (ArrayIndexOutOfBoundsException e) {
[Link]("Array index error: " + [Link]());
}
catch (ArithmeticException e) {
[Link]("Math error: " + [Link]());
}
catch (Exception e) {
[Link]("General exception: " + e);
}
[Link]("Program continues...");
}
}
Nested try Blocks
public class NestedTryDemo {
A try block can be inside another try block. public static void main(String[] args) {
try {
Used when code in both inner and outer blocks can // Outer try block
throw exceptions. int numbers[] = {10, 20, 30};
Each time a try statement is entered, the context of that try {
exception is pushed on the stack. // Inner try block
int result = numbers[5] / 0; // two possible exceptions
If an inner try statement does not have a catch handler }
for a particular exception, the next try statement’s catch catch (ArrayIndexOutOfBoundsException e) {
handlers are inspected for a match. [Link]("Inner catch: Invalid array index");
}
This continues until one of the catch statements
succeeds, or until all of the nested try statements are [Link]("Outer try continues...");
}
exhausted. catch (ArithmeticException e) {
If no catch statement matches, then the Java run-time [Link]("Outer catch: Division by zero");
}
system will handle the exception.
[Link]("Program continues after nested try...");
}
}
The throw Keyword
We have only been catching exceptions that are
thrown by the Java runtime system.
public class ThrowDemo {
However, it is possible for your program to throw public static void main(String[] args) {
an exception explicitly, using the throw statement. int age = 15;
if (age < 18) {
throw new ArithmeticException("Not eligible to
throw new ExceptionType("Message"); vote");
}
[Link]("You can vote!");
}
}
Throwing a Custom Exception
class InvalidAgeException extends Exception {
InvalidAgeException(String msg) {
super(msg); public static void main(String[] args) {
} CustomThrow c = new CustomThrow();
} try {
[Link](16);
public class CustomThrow { } catch (InvalidAgeException e) {
void register(int age) throws InvalidAgeException { [Link]("Caught exception: " +
if (age < 18) { [Link]());
throw new InvalidAgeException("Age must be 18 or }
above"); }
} }
[Link]("Registration successful!");
}
The throws Keyword
The throws keyword is used in a method declaration to specify what exceptions the method
might throw.
Caller must handle or rethrow these exceptions.
Syntax:
returnType methodName (parameters) throws ExceptionType1, ExceptionType2 {
// method body
}
Example
import [Link].*;
public static void main(String[] args) {
public class ThrowsDemo { ThrowsDemo td = new ThrowsDemo();
void readFile() throws IOException { try {
FileReader fr = new FileReader("[Link]"); // may throw [Link]();
IOException } catch (IOException e) {
BufferedReader br = new BufferedReader(fr); [Link]("Handled exception: " +
[Link]([Link]()); [Link]());
} }
}
}
readFile() declares throws IOException.
The caller (main) must handle it using try-catch.
Difference Between throw and throws
Aspect throw throws
Use Actually generates/throws exception Declares possible exceptions in method signature
Position Inside method body In method declaration
Number One exception object at a time Can declare multiple exceptions
Example throw new IOException("File error"); void read() throws IOException
The finally Block
When exceptions are thrown execution in a method takes a
nonlinear path that alters the normal flow through the
method.
try {
It is even possible for an exception to cause the method to // risky code
return prematurely. } catch (ExceptionType e) {
This could be a problem in some methods. For example, if // exception handler
a method opens a file upon entry and closes it upon exit, } finally {
then it is not desirable that exception handling mechanism // cleanup code (always executed)
bypasses the file closing statement. }
The finally keyword is designed to address this problem.
Example
public class FinallyDemo {
public static void main(String[] args) {
try {
int data = 50 / 10;
[Link]("Result: " + data);
} catch (ArithmeticException e) {
[Link]("Exception caught: " + e);
} finally {
[Link]("Finally block always executes");
}
[Link]("Program continues...");
}
}
Multi-catch in Java 7+
A single catch block can handle multiple exceptions.
try {
int arr[] = new int[5];
arr[10] = 50; // ArrayIndexOutOfBounds
} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
[Link]("Exception occurred: " + e);
}
Java’s Built-in Exceptions
Category Exception Description / When it Occurs
Unchecked (Runtime) Thrown when an illegal arithmetic operation occurs
ArithmeticException
Exceptions (e.g., divide by zero).
NullPointerException Accessing a method/field on a null object reference.
ArrayIndexOutOfBoundsException Accessing an array index that does not exist.
StringIndexOutOfBoundsException Accessing a character position outside the string length.
ClassCastException Invalid type casting between incompatible objects.
Converting a string to a number fails (e.g., "abc" →
NumberFormatException
int).
IllegalArgumentException A method receives an inappropriate argument.
IllegalStateException A method is invoked at an illegal or inappropriate time.
When an operation is not supported (e.g., unmodifiable
UnsupportedOperationException
collections).
Java’s Built-in Exceptions
Checked Exceptions IOException Input-output operation fails (file not found, read/write issues).
FileNotFoundException Attempting to open a file that does not exist.
SQLException Error occurs when accessing a database.
ClassNotFoundException A class is not found when loading dynamically.
If an object does not implement Cloneable but clone() is
CloneNotSupportedException
called.
InterruptedException A thread is interrupted while waiting/sleeping.
InstantiationException Trying to create an instance of an abstract class or interface.
Errors (Not meant to be
OutOfMemoryError JVM runs out of heap memory.
handled)
StackOverflowError Deep or infinite recursion causes stack memory exhaustion.
VirtualMachineError Serious JVM error (internal failure).
Chained Exceptions
Definition
◦ A chained exception is an exception that is caused by another exception.
For example, imagine a situation in which a method throws an ArithmeticException because of
an attempt to divide by zero. However, the actual cause of the problem was that an I/O error
occurred, which caused the divisor to be set improperly.
All Throwable classes (like Exception, Error) support chaining:
◦ Throwable(String message, Throwable cause)
◦ Throwable(Throwable cause)
◦ Methods:
◦ getCause() → Returns the original cause.
◦ initCause(Throwable cause) → Sets the cause.
Example-using getCause()
public class ChainedExceptionDemo {
public static void main(String[] args) {
try {
try {
int result = 10 / 0; // root cause
} catch (ArithmeticException e) {
throw new RuntimeException("Calculation failed",
e);
}
} catch (RuntimeException ex) {
[Link]("Caught: " + ex);
[Link]("Original cause: " + [Link]());
}
}
}
Example-using initCause()
try {
NumberFormatException ex = new
NumberFormatException("Conversion error");
[Link](new NullPointerException("Null input"));
throw ex;
} catch (NumberFormatException e) {
[Link]("Caught: " + e);
[Link]("Cause: " + [Link]());
}