Loading...

Go Back

Next page
Go Back Course Outline

Java Full Course


Exception Handling in Java

Master error handling to build robust and fault-tolerant Java applications

Errors vs Exceptions

Java distinguishes between errors and exceptions, both of which are subclasses of Throwable.

Throwable
Error
Exception

Key Differences:

Feature Errors Exceptions
Type Unrecoverable Recoverable
Examples OutOfMemoryError, StackOverflowError IOException, SQLException, NullPointerException
Handling Should not be caught or handled Should be caught and handled
Package java.lang.Error java.lang.Exception

Important: Errors indicate serious problems that a reasonable application should not try to catch, while exceptions indicate conditions that an application might want to catch and handle.

try, catch, finally, throw, throws

Java provides five keywords for exception handling: try, catch, finally, throw, and throws.

Basic Exception Handling:

try-catch-finally Example
public class ExceptionDemo {
    public static void main(String[] args) {
        try {
            // Code that may throw an exception
            int result = divide(10, 0);
            System.out.println("Result: " + result);
        } catch (ArithmeticException e) {
            // Handle the exception
            System.out.println("Error: " + e.getMessage());
        } finally {
            // Always executed
            System.out.println("Finally block executed");
        }
    }
    
    public static int divide(int a, int b) {
        return a / b;
    }
}
Output:
Error: / by zero
Finally block executed

throw and throws:

throw and throws Example
public class ThrowExample {
    public static void main(String[] args) {
        try {
            checkAge(15);
        } catch (ArithmeticException e) {
            System.out.println("Exception: " + e.getMessage());
        }
    }
    
    // Method declares it may throw an exception
    public static void checkAge(int age) throws ArithmeticException {
        if (age < 18) {
            // Throw an exception
            throw new ArithmeticException("Access denied - You must be at least 18 years old");
        } else {
            System.out.println("Access granted");
        }
    }
}
Output:
Exception: Access denied - You must be at least 18 years old
1
Code in try block executes
2
If exception occurs, catch block handles it
3
Finally block always executes
Built-in Exception Classes

Java provides a rich hierarchy of exception classes in the java.lang package.

Common Exception Classes:

Exception Description Type
NullPointerException Attempt to use null where an object is required Unchecked
ArrayIndexOutOfBoundsException Access array with illegal index Unchecked
ArithmeticException Arithmetic error (divide by zero) Unchecked
IOException I/O operation failure Checked
SQLException Database access error Checked
ClassNotFoundException Class not found Checked

Checked vs Unchecked: Checked exceptions must be declared or handled, while unchecked exceptions (RuntimeException and its subclasses) do not require explicit handling.

Multiple Catch Blocks
public class MultipleCatch {
    public static void main(String[] args) {
        try {
            int[] arr = new int[5];
            arr[10] = 50; // ArrayIndexOutOfBoundsException
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Array index error: " + e.getMessage());
        } catch (ArithmeticException e) {
            System.out.println("Arithmetic error: " + e.getMessage());
        } catch (Exception e) {
            System.out.println("General exception: " + e.getMessage());
        }
    }
}
Output:
Array index error: Index 10 out of bounds for length 5
Custom Exceptions

You can create your own exception classes to represent specific error conditions in your application.

Creating Custom Exceptions:

Custom Exception Example
// Custom exception class
class InsufficientFundsException extends Exception {
    private double amount;
    
    public InsufficientFundsException(double amount) {
        super("Insufficient funds: " + amount);
        this.amount = amount;
    }
    
    public double getAmount() {
        return amount;
    }
}

class BankAccount {
    private double balance;
    
    public BankAccount(double balance) {
        this.balance = balance;
    }
    
    public void withdraw(double amount) throws InsufficientFundsException {
        if (amount > balance) {
            throw new InsufficientFundsException(amount - balance);
        }
        balance -= amount;
        System.out.println("Withdrawn: $" + amount);
    }
}

public class CustomExceptionDemo {
    public static void main(String[] args) {
        BankAccount account = new BankAccount(500);
        
        try {
            account.withdraw(100);
            account.withdraw(600);
        } catch (InsufficientFundsException e) {
            System.out.println("Error: " + e.getMessage());
            System.out.println("You need $" + e.getAmount() + " more");
        }
    }
}
Output:
Withdrawn: $100.0
Error: Insufficient funds: 200.0
You need $200.0 more

Best Practice: Custom exceptions should extend Exception for checked exceptions or RuntimeException for unchecked exceptions. Provide meaningful error messages and additional context where appropriate.

Exception Propagation

Exception propagation refers to the process where an exception is passed from method to method up the call stack until it's caught.

1
Exception occurs in methodA()
2
methodA() doesn't handle exception, passes to methodB()
3
methodB() doesn't handle exception, passes to methodC()
4
methodC() handles the exception
Exception Propagation Example
public class ExceptionPropagation {
    public static void main(String[] args) {
        try {
            methodA();
        } catch (Exception e) {
            System.out.println("Exception handled in main: " + e.getMessage());
        }
    }
    
    static void methodA() {
        System.out.println("In methodA");
        methodB();
    }
    
    static void methodB() {
        System.out.println("In methodB");
        methodC();
    }
    
    static void methodC() {
        System.out.println("In methodC");
        // This will cause an exception
        int result = 10 / 0;
        System.out.println("Result: " + result);
    }
}
Output:
In methodA
In methodB
In methodC
Exception handled in main: / by zero

Propagation with throws:

Propagation with throws
import java.io.*;

public class ThrowsPropagation {
    public static void main(String[] args) {
        try {
            readFile();
        } catch (IOException e) {
            System.out.println("File error: " + e.getMessage());
        }
    }
    
    // Propagate exception using throws
    static void readFile() throws IOException {
        FileReader file = new FileReader("nonexistent.txt");
        BufferedReader reader = new BufferedReader(file);
        System.out.println(reader.readLine());
        reader.close();
    }
}
Output:
File error: nonexistent.txt (The system cannot find the file specified)
Go Back

Next page