Java Exception Handling
An Exception is an event that occurs during program execution and disrupts the normal flow of instructions. Java provides a powerful exception handling framework that allows developers to gracefully catch and handle these errors, creating more robust and reliable applications.
What is an Exception?
In Java, an exception is an object that encapsulates detailed information about an error, such as the type of error and the state of the program when the error occurred. When an error occurs, the system creates an exception object and "throws" it.
Exception Classification
All exception objects are subclasses of the java.lang.Throwable class. Throwable has two main subclasses: Error and Exception.
Error: Represents serious problems that applications typically cannot handle, such asOutOfMemoryErrororStackOverflowError. Programs generally should not attempt to catchError.Exception: Represents exceptional situations that applications can handle. It is further divided into two categories:- Checked Exceptions: These exceptions must be handled at compile time, otherwise the code won't compile. They are usually external, unforeseeable errors, such as
IOException(file not found). Developers must either catch them withtry-catchor declare them withthrows. - Unchecked Exceptions (Runtime Exceptions): These exceptions are not checked at compile time and are usually caused by programming logic errors, such as
NullPointerException,ArrayIndexOutOfBoundsException, orArithmeticException(like division by zero). While they can be caught, a better approach is to fix the code logic to avoid them.
- Checked Exceptions: These exceptions must be handled at compile time, otherwise the code won't compile. They are usually external, unforeseeable errors, such as
try-catch Statement
This is the core mechanism for handling exceptions. Place code that might throw an exception in the try block, and use catch blocks to catch and handle specific types of exceptions.
public class TryCatchExample {
public static void main(String[] args) {
try {
// Code that might cause an exception
int[] numbers = {1, 2, 3};
System.out.println(numbers[5]); // Array index out of bounds
} catch (ArrayIndexOutOfBoundsException e) {
// Catch and handle the exception
System.out.println("Error: Array index out of range!");
// Print exception stack trace for debugging
e.printStackTrace();
}
System.out.println("Program continues...");
}
}A try block can be followed by multiple catch blocks to handle different types of exceptions.
The finally Keyword
Code in the finally block is guaranteed to execute regardless of whether an exception occurs (unless the JVM exits). It is typically used to release resources, such as closing file streams or database connections.
import java.io.*;
public class FinallyExample {
public static void main(String[] args) {
PrintWriter writer = null;
try {
writer = new PrintWriter(new FileWriter("output.txt"));
writer.println("Hello, World!");
} catch (IOException e) {
System.err.println("File write failed: " + e.getMessage());
} finally {
// Ensure writer is always closed
if (writer != null) {
writer.close();
System.out.println("PrintWriter closed.");
}
}
}
}throw and throws Keywords
throw: Used to actively throw an exception object in code. Typically used to report custom error conditions.javapublic void checkAge(int age) { if (age < 18) { throw new IllegalArgumentException("Age must be 18 or older"); } System.out.println("Age is valid."); }throws: Used in method signatures to declare that the method might throw one or more types of checked exceptions. It tells the method's caller that these declared exceptions must be handled when calling this method.javaimport java.io.IOException; // Declare that this method might throw IOException public void readFile(String filePath) throws IOException { // ... code to read file ... } // Caller must handle this exception public void processFile() { try { readFile("myFile.txt"); } catch (IOException e) { System.err.println("Error processing file."); } }
try-with-resources Statement (Java 7+)
For resources that implement the java.lang.AutoCloseable interface (such as file streams, database connections), the try-with-resources statement can greatly simplify resource management. It ensures that resources are automatically closed after the try block completes, eliminating the need for a manual finally block.
import java.io.*;
public class TryWithResourcesExample {
public static void main(String[] args) {
// writer will be automatically closed when try block ends
try (PrintWriter writer = new PrintWriter(new FileWriter("log.txt"))) {
writer.println("This is an auto-managed log entry.");
} catch (IOException e) {
System.err.println("Log write failed: " + e.getMessage());
}
}
}This is the recommended way to handle resources in modern Java.