Chapter 36: Exception Handling - Part 3 of Full Stack Java Development Series

Rohit GawandeRohit Gawande
21 min read

Introduction

In the world of programming, errors and unexpected situations are inevitable. As developers, we must anticipate and handle these situations gracefully to ensure our applications remain robust, reliable, and user-friendly. This is where exception handling in Java plays a pivotal role. It provides a structured and effective mechanism to detect and respond to runtime issues without compromising the application's overall integrity.

Importance of Exception Handling in Java

  1. Robust Error Management:
    Exception handling ensures that applications can identify and respond to unexpected conditions without abruptly terminating. This robustness allows programs to handle errors in a controlled manner, maintaining smooth operation and delivering a better user experience.

  2. Maintains Application Flow:
    By catching and resolving exceptions during runtime, developers can prevent abrupt crashes that may disrupt users or cause data loss. Proper handling ensures that the application can recover from failures and continue its operation, wherever feasible.

  3. Prevention of Undefined Behavior:
    Unhandled errors often lead to unpredictable results, which can jeopardize data integrity and security. Exception handling helps mitigate such risks by providing a systematic way to address potential failures.

What We Will Cover in Part 3

In this section, we will delve deeper into advanced exception-handling techniques, focusing on topics that enhance the precision and flexibility of error management in Java. Specifically, we will explore:

  1. Custom Exceptions:
    Learn how to create and use user-defined exceptions to address application-specific error conditions effectively.

  2. Nested Try-Catch Blocks:
    Understand how to manage complex scenarios involving multiple error-prone operations by nesting try-catch blocks strategically.

  3. Exception Control Flow:
    Discover how exceptions alter the natural flow of program execution and how to design applications to manage these deviations seamlessly.

  4. Additional Insights and Best Practices:
    Gain knowledge of essential tips and common pitfalls to ensure your exception-handling code is efficient and maintainable.

By mastering these advanced techniques, you'll be equipped to build resilient applications that can gracefully navigate the complexities of runtime errors.

1. Custom Exceptions (User-defined Exceptions)

Definition

A custom exception is a user-defined exception class that extends Exception or RuntimeException. It allows developers to create specific exceptions tailored to the application's unique requirements, making error handling more meaningful and contextually relevant.


When to Create Custom Exceptions

  • When existing exceptions (like ArithmeticException or IOException) don’t provide sufficient context for the error.

  • To distinguish specific errors in the application for targeted handling.

  • For clear and self-explanatory exception messages that improve debugging and maintenance.


Syntax for Custom Exceptions

public class CustomException extends Exception {
    public CustomException(String message) {
        super(message); // Pass the custom message to the parent class (Exception)
    }
}

Example

public class TestCustomException {
    public static void main(String[] args) {
        try {
            // Throwing a custom exception
            throw new CustomException("This is a custom exception");
        } catch (CustomException e) {
            System.out.println("Caught custom exception: " + e.getMessage());
        }
    }
}

// Output:
// Caught custom exception: This is a custom exception

Handling Custom Exceptions

While handling custom exceptions, follow these best practices:

  1. Meaningful Class Names:
    Name your exceptions descriptively, e.g., InvalidUserInputException.

  2. Specific Purpose:
    Each custom exception should represent a unique error scenario.

  3. Detailed Messages:
    Include helpful error messages for clarity during debugging.

  4. Documentation:
    Clearly document when and why the exception should be thrown.


2. Nested Try-Catch Blocks

Concept

Nested try-catch blocks allow error handling at multiple levels within a single method. A try block can include another try-catch block inside it to manage specific exceptions separately.

Key Points

  1. A try block can be nested:

    • Inside another try block.

    • Inside a catch block.

    • Inside a finally block.

  2. If an inner try block's exception is not caught, it propagates to the outer catch block.


Example 1: Handling Exceptions at Multiple Levels

public class NestedTryCatchExample {
    public static void main(String[] args) {
        try {
            System.out.println("Inside outer try");
            try {
                System.out.println("Inside inner try");
                System.out.println(10 / 0); // ArithmeticException occurs here
            } catch (ArithmeticException e) {
                System.out.println("Inside inner catch");
            }
            System.out.println("Outside inner try-catch");
        } catch (Exception e) {
            System.out.println("Inside outer catch");
        } finally {
            System.out.println("Inside outer finally");
        }
    }
}

// Output:
// Inside outer try
// Inside inner try
// Inside inner catch
// Outside inner try-catch
// Inside outer finally

Example 2: Inner Exception Not Handled

If the inner catch block doesn’t handle the exception, it propagates to the outer catch block:

public class NestedTryCatchExample {
    public static void main(String[] args) {
        try {
            System.out.println("Inside outer try");
            try {
                System.out.println("Inside inner try");
                System.out.println(10 / 0); // ArithmeticException occurs here
            } catch (NullPointerException e) {
                System.out.println("Inside inner catch");
            }
            System.out.println("Outside inner try-catch");
        } catch (Exception e) {
            System.out.println("Inside outer catch");
        } finally {
            System.out.println("Inside outer finally");
        }
    }
}

// Output:
// Inside outer try
// Inside inner try
// Inside outer catch
// Inside outer finally

Example 3: Multi-Catch with Nested Try

Multi-catch in the outer block can handle multiple exception types:

public class MultiCatchExample {
    public static void main(String[] args) {
        try {
            System.out.println("Inside outer try");
            System.out.println(10 / 0); // ArithmeticException occurs here
        } catch (ArithmeticException | NullPointerException e) {
            System.out.println("Inside outer catch");
        } finally {
            System.out.println("Inside outer finally");
        }
        System.out.println("Statement after outer finally");
    }
}

// Output:
// Inside outer try
// Inside outer catch
// Inside outer finally
// Statement after outer finally

Key Takeaways for Nested Try-Catch

  • Exceptions propagate to the nearest handler.

  • The finally block always executes, regardless of whether an exception occurred or not.

  • Avoid excessive nesting for readability and maintainability.


Additional Topics in This Class Agenda

  1. Custom Exception or User-defined Exception
    Explored above with syntax and examples.

  2. Valid and Invalid Ways of Using Try-Catch and Finally
    Learn about legal placements and sequences of try-catch-finally.

  3. Control Flow in Nested Try-Catch
    Detailed behavior of exception propagation through nested blocks.

  4. Synchronous vs. Asynchronous Exceptions
    Understand the differences in error-handling mechanisms.


2. Control Flow with Nested Try and Catch Blocks

In Java, the flow of execution through nested try, catch, and finally blocks depends on whether exceptions occur and where they are handled. Each section will provide a clear explanation of how control moves and which statements execute.


Code Template

try {
    statement-1;
    statement-2; // Possible exception point
    statement-3;
    try {
        statement-4;
        statement-5; 
        statement-6;
    }
    catch (xxx e) {
        statement-7;
    }
    finally {
        statement-8;
    }
    statement-9;
}
catch (yyy e) {
    statement-10;
}
finally {
    statement-11;
}
statement-12;

We will analyze this code for three specific cases:


Case 1: No Exception Occurs

  • Explanation:

    • All the try blocks execute without interruption.

    • Since no exception occurs, no catch block is executed.

    • The finally blocks execute sequentially after their corresponding try blocks.

    • After exiting the outer try-finally, the program continues to execute the remaining statements.

  • Flow:

    1. statement-1, statement-2, statement-3 execute sequentially.

    2. Enter the inner try block.

    3. statement-4, statement-5, statement-6 execute sequentially.

    4. The inner finally block executes (statement-8).

    5. Exit the inner try-finally.

    6. Execute statement-9 in the outer try.

    7. The outer finally block executes (statement-11).

    8. Finally, execute statement-12.

  • Executed Statements:
    1, 2, 3, 4, 5, 6, 8, 9, 11, 12.

  • Skipped Statements:
    7, 10 (as no exception occurs).

  • Result: Normal Termination.


Case 2: Exception Occurs at statement-2 and is Handled by the Outer Catch Block

  • Explanation:

    • statement-1 executes.

    • An exception occurs at statement-2. The control skips the rest of the outer try block (statement-3 and inner try-catch-finally) and directly moves to the outer catch block (yyy e).

    • After handling the exception in the catch block, the outer finally block executes.

    • The program then continues to statement-12.

  • Flow:

    1. Execute statement-1.

    2. Exception occurs at statement-2.

    3. Skip statement-3 and inner try-catch-finally.

    4. Execute the outer catch block (statement-10).

    5. Execute the outer finally block (statement-11).

    6. Continue to statement-12.

  • Executed Statements:
    1, 10, 11, 12.

  • Skipped Statements:
    2 (restarts due to exception), 3, 4, 5, 6, 7, 8, 9.

  • Result: Normal Termination.


Case 3: Exception Occurs at statement-2, but the Outer Catch Block Cannot Handle It

  • Explanation:

    • statement-1 executes.

    • An exception occurs at statement-2. The control attempts to find a matching catch block. If no matching catch block exists, the exception propagates.

    • The finally block associated with the outer try executes.

    • After this, the program terminates abnormally because the exception remains unhandled.

  • Flow:

    1. Execute statement-1.

    2. Exception occurs at statement-2.

    3. Skip all subsequent statements in the outer try block, including the inner try-catch-finally.

    4. The outer finally block (statement-11) executes.

    5. Abnormal termination occurs as no handler is found.

  • Executed Statements:
    1, 11.

  • Skipped Statements:
    2 (restarts due to exception), 3, 4, 5, 6, 7, 8, 9, 10, 12.

  • Result: Abnormal Termination.


Case Analysis Table

CaseExecuted StatementsResult
No Exception Occurs1, 2, 3, 4, 5, 6, 8, 9, 11, 12Normal Termination
Exception at statement-2 (Handled)1, 10, 11, 12Normal Termination
Exception at statement-2 (Unhandled)1, 11Abnormal Termination

This step-by-step breakdown explains how the control flow behaves depending on the occurrence and handling of exceptions, ensuring every detail is covered.


Case 4: Exception Occurs at statement-5, and the Inner Catch Block is Matched

  • Explanation:

    • The outer try block executes statement-1, statement-2, and statement-3 sequentially.

    • The inner try block executes statement-4.

    • An exception occurs at statement-5, and the inner catch block (xxx e) matches the exception type.

    • Control moves to the inner catch block, and statement-7 is executed.

    • The inner finally block (statement-8) always executes after the catch block.

    • The control skips the remaining inner try statements (statement-6) and continues with the outer try-finally.

    • statement-9 is skipped, and the outer finally block executes (statement-11).

    • Program terminates normally after executing statement-12.

  • Flow:

    1. statement-1, statement-2, statement-3.

    2. Enter inner try: execute statement-4.

    3. Exception at statement-5 → move to inner catch block (statement-7).

    4. Execute inner finally block (statement-8).

    5. Skip statement-6 and statement-9.

    6. Execute outer finally block (statement-11).

    7. Execute statement-12.

  • Executed Statements:
    1, 2, 3, 4, 7, 8, 11, 12.

  • Skipped Statements:
    5, 6, 9, 10.

  • Result: Normal Termination.


Case 5: Exception Occurs at statement-5, Inner Catch Block is Not Matched, but Outer Catch Block is Matched

  • Explanation:

    • The outer try block executes statement-1, statement-2, and statement-3.

    • The inner try block executes statement-4.

    • An exception occurs at statement-5, but the inner catch block (xxx e) does not match the exception type.

    • Control skips the inner catch block and executes the inner finally block (statement-8).

    • Control propagates to the outer catch block (yyy e), which matches the exception type.

    • After handling the exception, the outer finally block executes (statement-11).

    • Program terminates normally after executing statement-12.

  • Flow:

    1. statement-1, statement-2, statement-3.

    2. Enter inner try: execute statement-4.

    3. Exception at statement-5 → inner catch block is skipped.

    4. Execute inner finally block (statement-8).

    5. Outer catch block (statement-10) matches the exception.

    6. Execute outer finally block (statement-11).

    7. Execute statement-12.

  • Executed Statements:
    1, 2, 3, 4, 8, 10, 11, 12.

  • Skipped Statements:
    5, 6, 7, 9.

  • Result: Normal Termination.


Case 6: Exception Occurs at statement-5, and Neither Inner nor Outer Catch Block Matches

  • Explanation:

    • The outer try block executes statement-1, statement-2, and statement-3.

    • The inner try block executes statement-4.

    • An exception occurs at statement-5, but neither the inner catch block (xxx e) nor the outer catch block (yyy e) matches the exception type.

    • Control skips all catch blocks and executes the finally blocks.

    • After executing the finally blocks, the program terminates abnormally due to the unhandled exception.

  • Flow:

    1. statement-1, statement-2, statement-3.

    2. Enter inner try: execute statement-4.

    3. Exception at statement-5 → both catch blocks are skipped.

    4. Execute inner finally block (statement-8).

    5. Execute outer finally block (statement-11).

    6. Abnormal termination due to unhandled exception.

  • Executed Statements:
    1, 2, 3, 4, 8, 11.

  • Skipped Statements:
    5, 6, 7, 9, 10, 12.

  • Result: Abnormal Termination.


Case Analysis Table

CaseExecuted StatementsResult
4: Inner Catch Block Matches1, 2, 3, 4, 7, 8, 11, 12Normal Termination
5: Outer Catch Block Matches1, 2, 3, 4, 8, 10, 11, 12Normal Termination
6: No Catch Block Matches1, 2, 3, 4, 8, 11Abnormal Termination

This detailed explanation ensures clarity about the control flow in nested try-catch-finally structures for each scenario.


Case 7: Exception Occurs at statement-7, and the Corresponding Catch Block is Matched

  • Explanation:

    • The outer try block executes statement-1, statement-2, and statement-3.

    • The inner try block executes statement-4, statement-5, and statement-6.

    • If an exception occurs during the execution of statement-4, statement-5, or statement-6, control will move to the inner catch block.

    • The exception matches the inner catch block, and statement-7 is executed.

    • The inner finally block (statement-8) will be executed regardless of the exception.

    • The control then skips the remaining inner try and catch blocks (statement-9 is skipped).

    • The outer catch block (yyy e) does not handle the exception, so control moves to the outer finally block (statement-11).

    • The program completes normally after executing statement-12.

  • Flow:

    1. statement-1, statement-2, statement-3.

    2. Enter inner try: execute statement-4, statement-5, and statement-6.

    3. Exception at statement-7 → move to inner catch block and execute statement-7.

    4. Execute inner finally block (statement-8).

    5. Skip statement-9.

    6. Execute outer finally block (statement-11).

    7. Execute statement-12.

  • Executed Statements:
    1, 2, 3, 8, 10, 11, 12.

  • Skipped Statements:
    4, 5, 6, 7, 9.

  • Result: Normal Termination.


Case 8: Exception Occurs at statement-7, and the Corresponding Catch Block is Not Matched

  • Explanation:

    • The outer try block executes statement-1, statement-2, and statement-3.

    • The inner try block executes statement-4, statement-5, and statement-6.

    • An exception occurs at statement-7 but the inner catch block does not match the exception type.

    • The inner catch block is skipped, but the inner finally block (statement-8) is still executed.

    • Control propagates to the outer catch block (statement-10), which does not handle the exception.

    • The outer finally block (statement-11) is executed.

    • The program terminates abnormally due to the unhandled exception.

  • Flow:

    1. statement-1, statement-2, statement-3.

    2. Enter inner try: execute statement-4, statement-5, and statement-6.

    3. Exception at statement-7 → inner catch block is skipped.

    4. Execute inner finally block (statement-8).

    5. Propagate to outer catch block (statement-10) which does not handle the exception.

    6. Execute outer finally block (statement-11).

    7. Abnormal termination due to unhandled exception.

  • Executed Statements:
    1, 2, 3, 8, 11.

  • Skipped Statements:
    4, 5, 6, 7, 9, 10, 12.

  • Result: Abnormal Termination.


Case Analysis Table

CaseExecuted StatementsResult
7: Exception at statement-7, inner catch block matched1, 2, 3, 8, 10, 11, 12Normal Termination
8: Exception at statement-7, inner catch block not matched1, 2, 3, 8, 11Abnormal Termination

This explanation clarifies the control flow for each case and demonstrates how the exception is handled in nested try-catch-finally blocks, considering whether the inner catch block matches the exception or not.


3. Possible Syntax to Write Try and Catch

Invalid Cases

  1. Case-1: Writing only try is invalid

    • You cannot have a try block without at least a catch or finally block.
    try {
        // Code that might throw an exception
    }
  1. Case-2: Writing only catch is invalid

    • A catch block must follow a try block to catch exceptions. A standalone catch is not allowed.
    catch (Exception e) {
        // Handle exception
    }
  1. Case-3: Writing only finally is invalid

    • A finally block cannot stand alone. It must follow a try block, optionally with a catch.
    finally {
        // Code to execute
    }
  1. Case-5: First catch block after the try block is not allowed

    • The catch block should always follow a try block. The reverse order (catch before try) is invalid.
    catch (Exception e) {
        // Handle exception
    }
    try {
        // Code that might throw an exception
    }
  1. Case-6: Multiple try and single catch not allowed

    • You cannot have multiple try blocks without corresponding catch blocks.
    try {
        // Code that might throw an exception
    }
    try {
        // Another block of code
    }
    catch (Exception e) {
        // Handle exception
    }
  1. Case-7: try-catch-try is not allowed

    • Multiple try blocks followed by a single catch block are not allowed.
    try {
        // Code that might throw an exception
    }
    catch (Exception e) {
        // Handle exception
    }
    try {
        // Another block of code
    }
  1. Case-10: Multiple catch blocks with the same exception class is not allowed

    • You do not need multiple catch blocks for the same exception type. A single catch block can handle the exception.
    try {
        // Code that might throw an exception
    }
    catch (Exception e) {
        // Handle exception
    }
    catch (Exception e) { // Invalid
        // Another handler for the same exception
    }
  1. Case-13: catch and finally are not allowed together directly

    • You cannot have a catch block followed directly by a finally block in isolation. There must be a try block before them.
    catch (Exception e) {
        // Handle exception
    }
    finally {
        // Code to execute
    }
  1. Case-15: try-finally followed by catch is not allowed

    • The order of blocks is important. You cannot have a catch block after a finally block.
    try {
        // Code that might throw an exception
    }
    finally {
        // Code to execute
    }
    catch (Exception e) {
        // Invalid: catch after finally
    }
  1. Case-17: Multiple finally blocks are not allowed
  • You can only have one finally block in a try-catch-finally structure.
try {
    // Code that might throw an exception
}
catch (Exception e) {
    // Handle exception
}
finally {
    // Code to execute
}
finally { // Invalid: multiple finally blocks
    // Another block
}
  1. Case-18: Statements in-between try-catch-finally are not allowed
  • No code can exist between the try, catch, and finally blocks.
try {
    // Code that might throw an exception
}
System.out.println("Hi"); // Invalid: Statements outside the blocks
catch (Exception e) {
    // Handle exception
}
System.out.println("Hello"); // Invalid: Statements outside the blocks
finally {
    // Code to execute
}

Valid Cases

  1. Case-4: Writing try and catch is valid

    • A try block followed by a catch block is a valid structure.
    try {
        // Code that might throw an exception
    }
    catch (Exception e) {
        // Handle exception
    }
  1. Case-8: Multiple try-catch blocks are allowed

    • You can have multiple try-catch blocks in sequence.
    try {
        // Code that might throw an exception
    }
    catch (Exception e) {
        // Handle exception
    }
    try {
        // Another block of code
    }
    catch (Exception e) {
        // Handle exception
    }
  1. Case-9: Multiple catch blocks with different exception classes is allowed

    • You can have multiple catch blocks for different exception classes.
    try {
        // Code that might throw an exception
    }
    catch (IOException e) {
        // Handle IOException
    }
    catch (SQLException e) {
        // Handle SQLException
    }
  1. Case-11: Writing two exception classes in one catch block is allowed

    • You can combine multiple exceptions in a single catch block.
    try {
        // Code that might throw an exception
    }
    catch (IOException | SQLException e) {
        // Handle IOException or SQLException
    }
  1. Case-12: try-catch-finally is allowed

    • A combination of try, catch, and finally is valid.
    try {
        // Code that might throw an exception
    }
    catch (Exception e) {
        // Handle exception
    }
    finally {
        // Code to execute
    }
  1. Case-16: try-multiple catch-finally is allowed

    • You can have multiple catch blocks followed by a finally block.
    try {
        // Code that might throw an exception
    }
    catch (IOException e) {
        // Handle IOException
    }
    catch (SQLException e) {
        // Handle SQLException
    }
    finally {
        // Code to execute
    }
  1. Case-19: Only try with resources is allowed

    • You can use the try block with resources (e.g., files, streams) using the try-with-resources syntax.
    try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
        // Code that reads the file
    } catch (IOException e) {
        // Handle IOException
    }

4. Asynchronous Exception vs Synchronous Exception

In Java, exceptions can be broadly classified into two types based on when and where they occur: Synchronous Exceptions and Asynchronous Exceptions. Let's explore both concepts in detail.

1. Synchronous Exception

A Synchronous Exception occurs at a specific point in the program where the error happens. The exception is directly tied to a particular statement or operation in the code. These are typically predictable errors that happen when an operation is performed that is inherently wrong at that specific moment.

Characteristics of Synchronous Exceptions:

  • Occurs at a specific position in the program.

  • The error is triggered by a particular action or statement in the code.

  • It can be predicted based on the code's behavior at runtime.

Common Examples of Synchronous Exceptions:

  1. ArithmeticException

    • This occurs when an arithmetic operation, such as division by zero, is attempted.

    • Example:

        public class Exception25 {
            public static void main(String[] args) {
                System.out.println(10 / 0);  // ArithmeticException
            }
        }
      
    • Explanation: Division by zero is invalid and throws an ArithmeticException at that point in the program.

    Exception in thread "main" java.lang.ArithmeticException: / by zero
        at Exception25.main(Exception25.java:3)
  1. ArrayIndexOutOfBoundsException

    • This occurs when you try to access an array element with an index that is out of the bounds of the array.

    • Example:

        public class Exception25 {
            public static void main(String[] args) {
                int[] a = new int[5];
                a[5] = 10;  // ArrayIndexOutOfBoundsException
            }
        }
      
    • Explanation:

      • The array a has 5 elements, indexed from 0 to 4. Trying to access a[5] (an index that does not exist) causes the

      • ArrayIndexOutOfBoundsException.

    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
        at Exception25.main(Exception25.java:5)
  1. NullPointerException

    • This occurs when an operation is performed on a null reference, such as calling a method on a null object.

    • Example:

        public class Exception25 {
            public static void main(String[] args) {
                String str = null;
                str.toUpperCase();  // NullPointerException
            }
        }
      
    • Explanation: Since str is null, calling toUpperCase() will throw a NullPointerException at runtime.

    Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.toUpperCase()" because "str" is null
        at Exception25.main(Exception25.java:4)

2. Asynchronous Exception

An Asynchronous Exception is less predictable and can occur anywhere in the program, typically in response to external factors like user input or system signals. These exceptions are not tied to a specific operation or statement, and they can interrupt the flow of the program at any time.

Characteristics of Asynchronous Exceptions:

  • The exception can occur at any point during program execution.

  • It is often triggered by external actions, such as interrupts or signals.

  • The error is harder to predict and handle.

Common Example of Asynchronous Exceptions:

  1. KeyboardInterrupt (CTRL+C)

    • This occurs when the program is waiting for user input, and the user presses CTRL+C to interrupt the program.

    • Example:

        import java.util.Scanner;
        public class Exception25 {
            public static void main(String[] args) {
                Scanner scan = new Scanner(System.in);
                System.out.println("Enter name");
                String name = scan.next();
                System.out.println("Enter grades");
                String grades = scan.next();
                System.out.println(grades);
            }
        }
      
    • Explanation: If the user presses CTRL+C while the program is waiting for input, a KeyboardInterrupt exception occurs, which terminates the program.

    • Output when CTRL+C is pressed:

        Enter name
        Rohit
        Enter grades
        CTRL+C --> Keyboard interrupt
        Exception in thread "main" Terminate batch job (Y/N)?
      

Summary of Differences:

FeatureSynchronous ExceptionAsynchronous Exception
OccurrenceOccurs at a specific program statement.Occurs anywhere during program execution.
PredictabilityCan be predicted based on the code.Hard to predict, often triggered by external factors.
Common ExampleArithmeticException, ArrayIndexOutOfBoundsException, NullPointerException.KeyboardInterrupt (CTRL+C), thread interruptions, etc.
Control Flow ImpactStops execution of the current statement.Can interrupt program execution at any point.

Understanding these two types of exceptions is crucial for writing robust and error-resistant code. Synchronous exceptions can typically be handled by anticipating the specific error, while asynchronous exceptions often require special handling for external events that may arise at any point during execution.


7. Error Propagation and Handler

  • From Exception to Handler

    • Explanation of how the code execution stops at the point where an exception is thrown and moves to the handler.
  • The Concept of Handlers

    • Catch blocks as handlers.
  • Flow of Execution: An Example

    • Show how certain lines in the code won’t execute once an exception occurs until it’s handled.

8. Advanced Handling Mechanisms

  • Exception Chaining

    • How exceptions can be chained in Java using Throwable.initCause().

    • Example: Chained Exceptions

    try {
        throw new IOException("IO Exception");
    } catch (IOException e) {
        try {
            throw new Exception("Wrapped Exception", e);
        } catch (Exception ex) {
            System.out.println(ex.getCause());
        }
    }
  • Using Multiple Catch Blocks for Complex Exception Handling

    • Handling a variety of exceptions in a single method and how each is managed.

9. Handling Checked and Unchecked Exceptions

  • Checked Exceptions

    • Must be either caught or declared to be thrown.
  • Unchecked Exceptions

    • Exceptions like RuntimeException that don’t require explicit handling.
  • Differences in Handling Strategies


10. Best Practices for Exception Handling

  • Handling Specific Exceptions First

    • How to handle specific exceptions before more general ones.
  • Don’t Use Exception Handling for Flow Control

    • Avoid using exceptions as a way to control program flow.
  • Avoid Empty Catch Blocks

  • Log Detailed Information for Debugging

  • Re-throwing Exceptions

    • Best practices when re-throwing exceptions after logging or processing them.

11. Try-With-Resources

  • What Is Try-With-Resources?

    • A new feature introduced in Java 7 that automatically closes resources (like files, network connections) when the try block finishes execution.
  • Syntax

      try (FileReader fr = new FileReader("file.txt")) {
          // Read the file
      } catch (IOException e) {
          // Handle exception
      }
    
  • Advantages of Try-With-Resources


0
Subscribe to my newsletter

Read articles from Rohit Gawande directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rohit Gawande
Rohit Gawande

🚀 Tech Enthusiast | Full Stack Developer | System Design Explorer 💻 Passionate About Building Scalable Solutions and Sharing Knowledge Hi, I’m Rohit Gawande! 👋I am a Full Stack Java Developer with a deep interest in System Design, Data Structures & Algorithms, and building modern web applications. My goal is to empower developers with practical knowledge, best practices, and insights from real-world experiences. What I’m Currently Doing 🔹 Writing an in-depth System Design Series to help developers master complex design concepts.🔹 Sharing insights and projects from my journey in Full Stack Java Development, DSA in Java (Alpha Plus Course), and Full Stack Web Development.🔹 Exploring advanced Java concepts and modern web technologies. What You Can Expect Here ✨ Detailed technical blogs with examples, diagrams, and real-world use cases.✨ Practical guides on Java, System Design, and Full Stack Development.✨ Community-driven discussions to learn and grow together. Let’s Connect! 🌐 GitHub – Explore my projects and contributions.💼 LinkedIn – Connect for opportunities and collaborations.🏆 LeetCode – Check out my problem-solving journey. 💡 "Learning is a journey, not a destination. Let’s grow together!" Feel free to customize or add more based on your preferences! 😊