1
try-catch Basics
A
Basic Syntax
The try-catch statement is the fundamental mechanism for handling exceptions in Java. You place code that might throw an exception inside the try block, and code that handles the exception inside the catch block.
try-catch Template
try {
// Code that might throw an exception
// (risky code goes here)
} catch (ExceptionType e) {
// Code to handle the exception
// (recovery / error message goes here)
}
How It Works
- Java executes the code inside the
try block.
- No exception? The
catch block is skipped entirely.
- Exception thrown? Java immediately jumps to the matching
catch block.
- Execution continues normally after the try-catch structure.
try { ... }
↓
No exception
↓
Skip catch
Exception thrown!
↓
catch { handle it }
↓
Continue after try-catch
B
Example: Safe Division
SafeDivision.java
public class SafeDivision {
public static void main(String[] args) {
try {
int result = 10 / 0; // This will throw ArithmeticException
System.out.println("Result: " + result); // This line is SKIPPED
} catch (ArithmeticException e) {
System.out.println("Error: Division by zero!");
}
System.out.println("Program continues normally.");
}
}
2
Multiple catch Blocks
A single try block can have multiple catch blocks, each handling a different type of exception.
MultipleCatch.java
import java.util.Scanner;
public class MultipleCatch {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[] numbers = {10, 20, 30};
boolean success = false;
do {
System.out.print("Enter an index (0-2): ");
int index = input.nextInt();
System.out.print("Enter a divisor: ");
int divisor = input.nextInt();
try {
int value = numbers[index]; // might throw ArrayIndexOutOfBoundsException
int result = value / divisor; // might throw ArithmeticException
System.out.println("Result = " + result);
success = true; // only reached if no exception
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Array index out of bounds! Try again.");
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero! Try again.");
}
} while (!success);
}
}
Important Ordering Rule
Catch blocks must be ordered from most specific to most general. Do not put the general Exception catch above a specific one — this is not good at all! The general catch would catch everything, and the specific catch block would never be reached.
WRONG
Compiler Error — General First
// WRONG - Compiler Error!
try {
int result = 10 / 0;
} catch (Exception e) { // General catches EVERYTHING
System.out.println("General error");
} catch (ArithmeticException e) { // UNREACHABLE! Compiler error
System.out.println("Math error");
}
CORRECT
Specific First, General Last
// CORRECT - Specific first, general last
try {
int result = 10 / 0;
} catch (ArithmeticException e) { // Specific: checked first
System.out.println("Math error");
} catch (Exception e) { // General: catches anything else
System.out.println("General error");
}
3
Multi-catch (Java 7+)
Starting with Java 7, you can catch multiple exception types in a single catch block using the pipe | operator. This eliminates duplicate code when the handling logic is the same.
MultiCatch.java
try {
// Some risky code
int[] arr = new int[5];
arr[10] = 50 / 0;
} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
System.out.println("Error occurred: " + e.getMessage());
}
Multi-catch Rules
- Exception types in a multi-catch cannot be related by inheritance. You cannot write
IOException | Exception because IOException is a subclass of Exception.
- The exception variable
e is implicitly final — you cannot reassign it inside the catch block.
4
Useful Exception Methods
Every exception object inherits useful methods from the Throwable class that help with debugging and error reporting.
ExceptionMethods.java
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
// 1. getMessage() - returns just the error message
System.out.println(e.getMessage());
// Output: / by zero
// 2. toString() - returns exception type + message
System.out.println(e.toString());
// Output: java.lang.ArithmeticException: / by zero
// 3. printStackTrace() - prints full stack trace
e.printStackTrace();
// Output: java.lang.ArithmeticException: / by zero
// at ExceptionMethods.main(ExceptionMethods.java:3)
}
What Each Method Returns
getMessage() — Returns only the description string (e.g., "/ by zero"). Best for showing user-friendly error messages.
toString() — Returns the exception class name + message (e.g., "java.lang.ArithmeticException: / by zero"). Good for logging.
printStackTrace() — Prints the complete call stack to the error stream. Most useful for debugging — shows exactly where the exception originated.
5
The finally Block
The finally block is ALWAYS executed — whether an exception occurs or not. It is the perfect place for cleanup code: closing files, releasing database connections, freeing resources. No matter what happens in the try or catch, the finally block runs.
A
Basic Syntax
try {
// Risky code
} catch (ExceptionType e) {
// Handle exception
} finally {
// ALWAYS executed - cleanup code goes here
}
try { ... }
↓
No exception
↓
Skip catch
Exception thrown!
↓
catch { handle it }
↓
finally { ALWAYS runs }
↓
Continue program
B
File Closing Example
Why finally Is Perfect for Cleanup
- If the program has no problem → close the file.
- If the program has a problem → close the file.
finally does this perfectly — it ensures the file is closed no matter what.
FileReaderExample.java
import java.io.*;
import java.util.*;
public class FileReaderExample {
public static void main(String[] args) {
Scanner scanner = null;
try {
scanner = new Scanner(new File("data.txt"));
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException e) {
System.out.println("File not found: " + e.getMessage());
} finally {
if (scanner != null) {
scanner.close(); // Always close the file!
System.out.println("Scanner closed.");
}
}
}
}
C
finally Runs Even with return
A common misconception is that return inside try would skip the finally block. It does not — finally always runs, even before a return statement takes effect.
FinallyWithReturn.java
public class FinallyWithReturn {
public static String testFinally() {
try {
System.out.println("Inside try");
return "try value"; // return is scheduled...
} finally {
System.out.println("Inside finally"); // ...but finally runs FIRST!
}
}
public static void main(String[] args) {
String result = testFinally();
System.out.println("Returned: " + result);
}
}
Three Valid Forms of try
try-catch — Handle the exception.
try-finally — No handling, but guarantee cleanup.
try-catch-finally — Handle and guarantee cleanup.
A try block must be followed by at least one catch or a finally (or both). A standalone try with nothing after it is a compiler error.
6
try-with-resources (Java 7+)
Writing finally blocks to close resources is tedious and error-prone. You have to remember to check for null, and the close() call itself can throw an exception! Java 7 introduced try-with-resources to solve this problem elegantly.
Before
Manual Cleanup with finally
Scanner scanner = null;
try {
scanner = new Scanner(new File("data.txt"));
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException e) {
System.out.println("File not found!");
} finally {
if (scanner != null) {
scanner.close(); // Tedious! Must remember null check
}
}
After
try-with-resources (Clean Version)
TryWithResources.java
try (Scanner scanner = new Scanner(new File("data.txt"))) {
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException e) {
System.out.println("File not found!");
}
// scanner is automatically closed here - no finally needed!
Benefits of try-with-resources
- No finally needed — Resources are automatically closed at the end of the try block.
- Automatic close() — Java calls
close() on the resource even if an exception occurs.
- Works with AutoCloseable — Any class that implements the
AutoCloseable interface (Scanner, BufferedReader, Connection, etc.) can be used.
- Cleaner code — No null checks, no nested try-catch for close().
Multi
Multiple Resources
You can declare multiple resources in a single try-with-resources, separated by semicolons. They are closed in reverse order of declaration.
MultipleResources.java
try (
Scanner input = new Scanner(new File("input.txt"));
PrintWriter output = new PrintWriter("output.txt")
) {
while (input.hasNextLine()) {
String line = input.nextLine();
output.println(line.toUpperCase());
}
} catch (FileNotFoundException e) {
System.out.println("File error: " + e.getMessage());
}
// Both input and output are automatically closed!
// Closed in reverse order: output first, then input
7
Summary
Key Takeaways
try-catch is the fundamental mechanism for handling exceptions — risky code in try, recovery code in catch.
- Multiple catch blocks must be ordered from most specific to most general.
- Multi-catch (Java 7+) uses the
| operator to handle multiple unrelated exceptions in one block.
getMessage(), toString(), and printStackTrace() help inspect exception details.
- The
finally block always executes — even when there is a return statement in try.
- try-with-resources (Java 7+) automatically closes resources that implement
AutoCloseable.
Up Next
In the next lesson, we will learn how to create our own custom exceptions — defining new exception classes tailored to our application's specific error conditions.