CS Engineering Gyan

Exception Handling in Java

No matter how carefully a program is written, unexpected situations can still occur during execution. A user might enter text where a number was expected, a file the program tries to open might not exist, or a calculation might attempt to divide by zero. Without a proper way to handle these situations, such errors would cause the entire program to crash abruptly.

Java addresses this challenge through a structured approach called exception handling, which allows a program to detect problems as they occur and respond to them gracefully, rather than terminating unexpectedly. This makes applications more reliable and provides a better experience for the people using them.

In this tutorial, you will learn what exceptions are, how the try-catch-finally structure works, the difference between checked and unchecked exceptions, how to use the throw and throws keywords, and how to create your own custom exceptions.


What is an Exception in Java?

An exception is an event that disrupts the normal flow of a program's execution, typically caused by an error condition that occurs while the program is running. When an exception occurs and is not handled, the program stops executing and displays an error message describing what went wrong.

Example Without Handling

public class UnhandledExceptionExample {

    public static void main(String[] args) {

        int[] weeklyViews = {1200, 1500, 1800};

        System.out.println("CS Engineering Gyan views: " + weeklyViews[5]);

    }

}

Output

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 3

In this example, attempting to access an index that does not exist in the array causes the program to terminate immediately with an error message, since there is no mechanism in place to handle this unexpected situation.


The try-catch Block

Java allows you to anticipate potential problems by placing risky code inside a try block, and defining how to respond to specific errors inside one or more catch blocks. If an exception occurs inside the try block, control immediately jumps to the matching catch block instead of crashing the program.

Syntax

try {

    // code that might cause an exception

} catch (ExceptionType e) {

    // code to handle the exception

}

Example

public class TryCatchExample {

    public static void main(String[] args) {

        int[] weeklyViews = {1200, 1500, 1800};

        try {

            System.out.println("CS Engineering Gyan views: " + weeklyViews[5]);

        } catch (ArrayIndexOutOfBoundsException e) {

            System.out.println("CS Engineering Gyan: Requested data is not available for that day.");

        }

    }

}

Output

CS Engineering Gyan: Requested data is not available for that day.

Instead of the program crashing, the catch block intercepts the exception and displays a friendly, informative message, allowing the rest of the program to continue running normally afterward.


The finally Block

The finally block contains code that always executes, regardless of whether an exception occurred or not. It is commonly used for cleanup tasks, such as closing files or releasing resources, that must happen no matter what.

Syntax

try {

    // risky code

} catch (ExceptionType e) {

    // handling code

} finally {

    // code that always runs

}

Example

public class FinallyExample {

    public static void main(String[] args) {

        try {

            int result = 100 / 0;

            System.out.println(result);

        } catch (ArithmeticException e) {

            System.out.println("CS Engineering Gyan: Cannot divide by zero.");

        } finally {

            System.out.println("CS Engineering Gyan: Calculation attempt completed.");

        }

    }

}

Output

CS Engineering Gyan: Cannot divide by zero.

CS Engineering Gyan: Calculation attempt completed.

Notice that the message inside the finally block is printed regardless of the exception, demonstrating that this block runs whether the try block succeeds or an exception is caught.


Multiple catch Blocks

A single try block can be followed by multiple catch blocks, allowing a program to handle different types of exceptions in different ways, depending on what specifically went wrong.

Example

public class MultipleCatchExample {

    public static void main(String[] args) {

        try {

            int[] subscriberData = {50000, 62000, 71000};

            System.out.println("CS Engineering Gyan subscribers: " + subscriberData[4]);

        } catch (ArrayIndexOutOfBoundsException e) {

            System.out.println("CS Engineering Gyan: Subscriber record not found.");

        } catch (Exception e) {

            System.out.println("CS Engineering Gyan: An unexpected error occurred.");

        }

    }

}

Output

CS Engineering Gyan: Subscriber record not found.

Java checks each catch block in order and executes the first one that matches the type of exception thrown. Placing the more general Exception catch block after specific ones ensures that specific exceptions are handled precisely, while unexpected ones are still caught safely.


Checked vs Unchecked Exceptions

Java classifies exceptions into two broad categories, based on whether the compiler forces you to handle them explicitly or not.

Checked Exceptions Unchecked Exceptions
Checked by the compiler during compilation. Not checked by the compiler, occurring during program execution.
Must be either caught or declared using the throws keyword. Handling them is optional, though recommended for reliability.
Examples include IOException and SQLException. Examples include ArithmeticException and NullPointerException.

Understanding this distinction helps explain why some exceptions must be explicitly handled in your code, while others can technically occur without the compiler forcing you to prepare for them in advance.


The throw Keyword

The throw keyword is used to manually trigger an exception within your code, typically when a specific condition indicates that something invalid has occurred, even if Java itself would not have thrown an exception automatically.

Example

public class ThrowExample {

    static void checkSubscriberCount(int count) {

        if (count < 0) {

            throw new IllegalArgumentException("Subscriber count cannot be negative.");

        }

        System.out.println("CS Engineering Gyan subscriber count: " + count);

    }

    public static void main(String[] args) {

        checkSubscriberCount(-500);

    }

}

Output

Exception in thread "main" java.lang.IllegalArgumentException: Subscriber count cannot be negative.

Since this exception is not caught anywhere in the example, the program terminates with the custom error message. In real applications, this kind of thrown exception would typically be caught and handled using a try-catch block.


The throws Keyword

The throws keyword is used in a method declaration to indicate that the method might throw a particular checked exception, passing the responsibility of handling it to whichever code calls the method.

Example

import java.io.IOException;

public class ThrowsExample {

    static void readChannelData() throws IOException {

        throw new IOException("Unable to read CS Engineering Gyan data file.");

    }

    public static void main(String[] args) {

        try {

            readChannelData();

        } catch (IOException e) {

            System.out.println("Error occurred: " + e.getMessage());

        }

    }

}

Output

Error occurred: Unable to read CS Engineering Gyan data file.

Here, the method readChannelData declares that it might throw an IOException using the throws keyword, requiring the calling code in the main method to handle that possibility using a try-catch block.


throw vs throws

throw throws
Used to actually trigger an exception at a specific point in the code. Used in a method signature to declare that an exception might occur.
Followed by a single exception object. Can list multiple exception types, separated by commas.
Used inside a method body. Used alongside a method declaration.

Creating Custom Exceptions

Java also allows developers to define their own exception classes, which is useful when built-in exception types do not accurately describe the specific problem occurring in an application.

Example

class InvalidVideoLengthException extends Exception {

    InvalidVideoLengthException(String message) {

        super(message);

    }

}

public class CustomExceptionExample {

    static void checkVideoLength(int minutes) throws InvalidVideoLengthException {

        if (minutes <= 0) {

            throw new InvalidVideoLengthException("Video length must be greater than zero minutes.");

        }

        System.out.println("CS Engineering Gyan video length: " + minutes + " minutes");

    }

    public static void main(String[] args) {

        try {

            checkVideoLength(-10);

        } catch (InvalidVideoLengthException e) {

            System.out.println("CS Engineering Gyan error: " + e.getMessage());

        }

    }

}

Output

CS Engineering Gyan error: Video length must be greater than zero minutes.

By extending the built-in Exception class, InvalidVideoLengthException becomes a fully functional custom exception, complete with its own descriptive error message that clearly reflects the specific problem being reported.


Common Built-in Exception Types

Exception Common Cause
ArithmeticException Occurs during invalid mathematical operations, such as division by zero.
ArrayIndexOutOfBoundsException Occurs when accessing an array index that does not exist.
NullPointerException Occurs when trying to use an object reference that has not been assigned a value.
NumberFormatException Occurs when attempting to convert an invalid string into a numeric type.
ClassCastException Occurs when attempting an invalid type conversion between objects.

Why Exception Handling Matters


Best Practices for Exception Handling


Common Mistakes Beginners Make

Mistake Correct Practice
Catching a general Exception when a specific exception type would be clearer. Catch the most specific exception type relevant to the situation first.
Leaving a catch block completely empty. Always include at least a message or logging statement inside a catch block.
Assuming the finally block will not run if an exception is caught. Remember that finally always executes, whether or not an exception occurred.
Confusing throw and throws in method design. Use throw to trigger an exception and throws to declare it in a method signature.

Frequently Asked Interview Questions

  1. What is an exception in Java?
    An exception is an event that disrupts the normal flow of program execution due to an unexpected error condition.
  2. What is the purpose of a try-catch block?
    It allows a program to detect and handle exceptions gracefully instead of crashing.
  3. When does the finally block execute?
    The finally block always executes, whether or not an exception was thrown or caught.
  4. What is the difference between checked and unchecked exceptions?
    Checked exceptions are verified by the compiler and must be handled, while unchecked exceptions occur at runtime without compiler enforcement.
  5. What is the difference between throw and throws?
    Throw is used to actually raise an exception, while throws is used in a method signature to declare a possible exception.
  6. Can a try block have multiple catch blocks?
    Yes, multiple catch blocks can be used to handle different types of exceptions separately.
  7. What is a custom exception in Java?
    A custom exception is a user-defined class that extends Exception to represent a specific application-related error.
  8. Why should catch blocks avoid being left empty?
    Because ignoring exceptions silently can hide real problems and make debugging significantly more difficult.

Summary

Exception handling allows Java programs to detect and respond to unexpected problems in a controlled, predictable manner, rather than crashing abruptly. By using try, catch, and finally blocks together, developers can isolate risky code, define specific responses to different error types, and guarantee that essential cleanup tasks always run.

Understanding the difference between checked and unchecked exceptions, along with the proper use of throw and throws, gives you the tools needed to write more robust and reliable applications. Custom exceptions further extend this capability, allowing you to define error types that accurately reflect the specific needs of your own programs.

With a solid understanding of exception handling, you are now ready to explore the Collections Framework, which provides powerful tools for storing and managing groups of data in Java.


← Previous: Object-Oriented Programming Next: Collections Framework →

Home Visit Our YouTube Channel