Java Tutorial 0/145 lessons ~6 min read Lesson 23

    Exception Handling

    java exception handling try catch finally throw throws checked unchecked runtime exception try with resources custom exception

    Course progress0%
    Focus
    27 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Introduction

    In every real-world application, unexpected situations can occur during program execution.

    For example:

    • A user enters invalid input.
    • A file does not exist.
    • A database connection fails.
    • A network request times out.
    • A division by zero occurs.
    • A required object is null.

    If these situations are not handled properly, the application may terminate unexpectedly, resulting in a poor user experience.

    Java provides a powerful Exception Handling mechanism that allows developers to gracefully handle runtime errors without crashing the application.

    Exception Handling is one of the most important topics in enterprise Java development and is extensively used in:

    • Spring Boot
    • Hibernate
    • REST APIs
    • Banking Systems
    • E-Commerce Applications
    • Android Development
    • Microservices
    • Distributed Systems

    In this lesson, you'll learn:

    • What is an Exception?
    • Exception Hierarchy
    • Errors vs Exceptions
    • Checked vs Unchecked Exceptions
    • try
    • catch
    • finally
    • Multiple Catch Blocks
    • Multi-Catch
    • throw
    • throws
    • Custom Exceptions
    • Try-with-Resources
    • Exception Chaining
    • Best Practices
    • Common Mistakes
    • Real-world Examples
    • Professional Interview Questions

    What is an Exception?

    An Exception is an event that interrupts the normal flow of program execution.

    Example:

    code
    int result = 10 / 0;

    Output:

    code
    Exception in thread "main"
    java.lang.ArithmeticException: / by zero

    Without exception handling, the program terminates immediately.

    Why Exception Handling?

    Without exception handling:

    code
    Program Starts
    Exception Occurs
    Application Crashes

    With exception handling:

    code
    Program Starts
    Exception Occurs
    Catch Exception
    Continue Execution

    Benefits:

    • Prevents application crashes
    • Improves user experience
    • Simplifies debugging
    • Separates business logic from error handling
    • Makes applications more reliable

    Exception Hierarchy

    Java exceptions are organized in a hierarchy.

    code
    Object
    Throwable
    / \
    Error Exception
    RuntimeException
    • Throwable is the root class.
    • Error represents serious JVM problems.
    • Exception represents conditions that applications can handle.
    • RuntimeException represents programming errors detected at runtime.

    Error vs Exception

    ErrorException
    Caused by JVMCaused by application or external factors
    Usually unrecoverableUsually recoverable
    Should not be caught in normal applicationsShould be handled appropriately
    Example: OutOfMemoryErrorExample: IOException

    Checked Exceptions

    Checked exceptions are verified by the compiler.

    Example:

    code
    import java.io.FileReader;
    public class Demo {
    public static void main(String[] args) {
    FileReader reader =
    new FileReader("data.txt");
    }
    }

    Compilation Error:

    code
    Unhandled exception:
    FileNotFoundException

    The compiler forces you to handle or declare checked exceptions.

    Common Checked Exceptions:

    • IOException
    • SQLException
    • FileNotFoundException
    • ClassNotFoundException

    Unchecked Exceptions

    Unchecked exceptions occur during runtime.

    Example:

    code
    String text = null;
    System.out.println(text.length());

    Output:

    code
    NullPointerException

    Common Runtime Exceptions:

    • NullPointerException
    • ArithmeticException
    • ArrayIndexOutOfBoundsException
    • NumberFormatException
    • IllegalArgumentException

    The try Block

    The try block contains code that may throw an exception.

    code
    try {
    int result = 10 / 0;
    }

    The catch Block

    The catch block handles the exception.

    code
    try {
    int result = 10 / 0;
    }
    catch (ArithmeticException ex) {
    System.out.println("Cannot divide by zero.");
    }

    Output:

    code
    Cannot divide by zero.

    The finally Block

    The finally block always executes, whether an exception occurs or not.

    code
    try {
    System.out.println("Opening File");
    }
    finally {
    System.out.println("Closing File");
    }

    Output:

    code
    Opening File
    Closing File

    Typical use cases:

    • Closing files
    • Releasing database connections
    • Closing network sockets
    • Cleaning resources

    Complete Example

    code
    try {
    int[] numbers = {1,2,3};
    System.out.println(numbers[5]);
    }
    catch(ArrayIndexOutOfBoundsException ex){
    System.out.println("Invalid Index");
    }
    finally{
    System.out.println("Execution Finished");
    }

    Output:

    code
    Invalid Index
    Execution Finished

    Multiple Catch Blocks

    Different exceptions can be handled separately.

    code
    try {
    String text = null;
    System.out.println(text.length());
    }
    catch(NullPointerException ex){
    System.out.println("Null Value");
    }
    catch(Exception ex){
    System.out.println("General Exception");
    }

    Always place more specific exceptions before more general ones.

    Multi-Catch (Java 7+)

    If multiple exceptions require identical handling:

    code
    try {
    // Code
    }
    catch(ArithmeticException |
    NumberFormatException ex){
    System.out.println("Invalid Input");
    }

    This reduces duplicate code.

    The throw Keyword

    throw explicitly throws an exception.

    Example:

    code
    public void withdraw(double amount){
    if(amount < 0){
    throw new IllegalArgumentException(
    "Amount cannot be negative");
    }
    }

    Output:

    code
    IllegalArgumentException:
    Amount cannot be negative

    The throws Keyword

    throws declares that a method may propagate an exception to its caller.

    code
    import java.io.IOException;
    public void readFile()
    throws IOException {
    }

    The calling method must then handle or declare the exception.

    throw vs throws

    throwthrows
    Throws an exception objectDeclares possible exceptions
    Used inside a methodUsed in the method signature
    Throws one exception instanceCan declare multiple exception types

    Custom Exceptions

    Custom exceptions represent application-specific business errors.

    Example:

    code
    class InsufficientBalanceException
    extends Exception {
    public InsufficientBalanceException(
    String message){
    super(message);
    }
    }

    Using it:

    code
    if(balance < amount){
    throw new InsufficientBalanceException(
    "Insufficient Balance");
    }

    Custom exceptions make business rules easier to understand and maintain.

    Try-with-Resources (Java 7+)

    Automatically closes resources that implement AutoCloseable.

    code
    import java.io.BufferedReader;
    import java.io.FileReader;
    try(BufferedReader reader =
    new BufferedReader(
    new FileReader("data.txt"))){
    System.out.println(reader.readLine());
    }
    catch(Exception ex){
    System.out.println(ex.getMessage());
    }

    Benefits:

    • Automatic resource cleanup
    • Less boilerplate code
    • Prevents resource leaks

    Exception Chaining

    One exception can wrap another.

    Example:

    code
    try{
    // Database Code
    }
    catch(Exception ex){
    throw new RuntimeException(
    "Database Error", ex);
    }

    This preserves the original cause while providing additional context.

    Real-World Example: Banking System

    code
    public void withdraw(double amount)
    throws InsufficientBalanceException{
    if(amount > balance){
    throw new InsufficientBalanceException(
    "Balance too low");
    }
    balance -= amount;
    }

    Real-World Example: REST API

    code
    try{
    service.save(employee);
    }
    catch(Exception ex){
    return ResponseEntity
    .internalServerError()
    .build();
    }

    In Spring Boot, centralized exception handling is commonly implemented using @ControllerAdvice and @ExceptionHandler.

    Best Practices

    Catch Specific Exceptions

    Prefer:

    code
    catch(IOException ex)

    Instead of:

    code
    catch(Exception ex)

    Specific exception handling improves clarity and avoids masking unrelated issues.

    Never Ignore Exceptions

    Avoid:

    code
    catch(Exception ex){
    }

    Always log, wrap, or handle exceptions appropriately.

    Use Custom Exceptions for Business Rules

    Domain-specific exceptions improve readability and make business logic easier to understand.

    Use Try-with-Resources

    Prefer automatic resource management for files, sockets, and database resources.

    Preserve the Root Cause

    When wrapping exceptions, pass the original exception as the cause.

    Common Mistakes

    Catching Exception Everywhere

    Overly broad exception handling can hide programming mistakes.

    Swallowing Exceptions

    Ignoring exceptions makes debugging extremely difficult.

    Using Exceptions for Normal Flow Control

    Exceptions should represent exceptional situations, not regular business logic.

    Forgetting Resource Cleanup

    Always release resources using try-with-resources or finally.

    Losing Stack Trace Information

    Avoid creating a new exception without preserving the original cause when appropriate.

    Hands-on Exercise

    Create a Java program that:

    1. Demonstrates ArithmeticException.
    2. Handles NullPointerException.
    3. Reads a file using try-with-resources.
    4. Creates multiple catch blocks.
    5. Uses multi-catch for two exception types.
    6. Creates a custom InvalidAgeException.
    7. Demonstrates the use of throw and throws.
    8. Wraps an exception using exception chaining.

    Summary

    Exception handling enables Java applications to respond gracefully to unexpected situations. By using try, catch, finally, throw, throws, custom exceptions, and try-with-resources, developers can build reliable, maintainable, and production-ready software. Proper exception handling is essential in enterprise applications and helps separate business logic from error recovery.

    Key Takeaways

    • Exceptions interrupt the normal flow of execution.
    • Throwable is the root of Java's exception hierarchy.
    • Checked exceptions are verified by the compiler.
    • Unchecked exceptions occur at runtime.
    • try encloses risky code.
    • catch handles exceptions.
    • finally executes regardless of success or failure.
    • throw explicitly creates and throws an exception.
    • throws declares exceptions in a method signature.
    • Try-with-resources automatically closes resources.
    • Custom exceptions improve business logic clarity.
    • Preserve exception causes when wrapping exceptions.

    Professional Interview Questions

    1What is the difference between Checked and Unchecked Exceptions?

    Professional Answer

    Checked exceptions are validated by the compiler and must either be handled using a try-catch block or declared using the throws keyword. They typically represent recoverable conditions such as file or database access failures. Unchecked exceptions extend RuntimeException and occur during program execution, usually indicating programming errors such as null references or invalid array indexes.

    Follow-up Questions

    • Why are checked exceptions called compile-time exceptions?
    • Give three examples of runtime exceptions.

    Interview Tip: Remember: Checked = Compiler forces handling, Unchecked = Runtime programming errors.

    2What is the difference between throw and throws?

    Professional Answer

    The throw keyword is used inside a method to explicitly create and throw an exception object. The throws keyword is used in a method declaration to indicate that the method may propagate one or more exceptions to its caller.

    Follow-up Questions

    • Can a method declare multiple exceptions with throws?
    • Can you throw checked and unchecked exceptions?

    Interview Tip: A simple rule: throw → Action, throws → Declaration.

    3What is Try-with-Resources, and why is it preferred?

    Professional Answer

    Try-with-resources is a Java feature introduced in Java 7 that automatically closes resources implementing the AutoCloseable interface after execution. It reduces boilerplate code, prevents resource leaks, and ensures resources are released even if an exception occurs.

    Follow-up Questions

    • Which interface must a resource implement?
    • Can multiple resources be declared in a single try-with-resources statement?

    Interview Tip: Prefer try-with-resources over manual cleanup in finally whenever working with files, streams, sockets, or database connections.

    Ready to mark this lesson complete?Track your journey across the entire course.