ZeroToSky
Java Tutorial 71 of 143
Basics
  • Introduction
  • Download and Install Java
  • Download and Install IntelliJ IDEA, Eclipse
  • Creating First Java Application in IntelliJ IDEA
  • JDK vs JRE vs JVM
  • Print output
  • Taking Input
  • Identifiers
  • Keywords
  • Variables
  • Data Types
  • Literals
  • Wrapper Classes
  • Operators
  • Decision Making
  • Loops and Jump Statements
  • Project: Number Guessing Game

All 17 lessons →

Methods
  • Introduction
  • Static Methods vs Instance Methods
  • Access Modifiers
  • Command Line Arguments
  • Variable Arguments (Varargs)

All 5 lessons →

Arrays
  • Introduction
  • One Dimensional Arrays
  • Multidimensional Arrays
  • Array Class
  • Arrays Class

All 5 lessons →

Strings
  • Introduction
  • String
  • StringBuffer
  • StringBuilder
  • String Class Methods
  • StringJoiner
  • StringTokenizer

All 7 lessons →

OOP & Interface

All 14 lessons →

Collections
  • Collection class
  • Collection Interface
  • List Interface
  • ArrayList
  • LinkedList
  • Set Interface
  • HashSet
  • LinkedHashSet
  • TreeSet
  • Queue Interface
  • PriorityQueue
  • Deque
  • ArrayDeque
  • Map Interface in Java
  • HashMap
  • LinkedHashMap
  • TreeMap
  • Hashtable
  • Iterator
  • Comparable and Comparator

All 20 lessons →

Exception Handling

All 7 lessons →

Multithreading & Concurrency
  • Introduction
  • Thread Class
  • Runnable Interface
  • Thread Life Cycle
  • Thread Priority
  • Synchronization
  • Inter-Thread Communication
  • Executor Framework
  • Callable and Future
  • Concurrent Collections

All 10 lessons →

Java 8 Features
  • Lambda Expressions
  • Functional Interfaces
  • Method References
  • Stream API
  • Optional Class
  • Default and Static Methods in Interface
  • Date and Time API

All 7 lessons →

Advanced Java Concepts
  • File Handling
  • Serialization and Deserialization
  • Reflection API
  • Annotations
  • Garbage Collection
  • Memory Management
  • JVM Architecture
  • Class Loading
  • Networking
  • Regular Expressions

All 10 lessons →

JDBC
  • Introduction
  • JDBC Driver
  • JDBC Connection
  • Types of Statements in JDBC
  • Transactions
  • ResultSet
  • Metadata
  • Connection Pooling

All 8 lessons →

GUI & Desktop
  • AWT
  • Swing
  • JavaFX

All 3 lessons →

Web & Enterprise
  • Servlets
  • JSP
  • Spring Framework
  • Spring Boot
  • Hibernate
  • REST API Development

All 6 lessons →

Practice Projects
  • Project: Number Guessing Game
  • Project: Banking System
  • Project: Student Management System
  • Project: Library Management System
  • Project: Quiz Application

All 5 lessons →

Quiz and Coding Practice
  • Java Topic-wise Quiz
  • Coding Practice Problems
  • Java Basics Coding Practice Problems
  • Java Exercises

All 4 lessons →

Interview Questions
  • Core Java Interview Questions and Answers
  • Advanced Java Interview Questions and Answers
  • Java Interview Questions

All 3 lessons →

DSA & Competitive Programming
  • Arrays and Strings
  • Linked List
  • Stack
  • Queue
  • Tree
  • Graph
  • Heap
  • Hashing
  • Sorting
  • Searching
  • Dynamic Programming
  • Roadmap for DSA in Java

All 12 lessons →

Java Try-Catch

Learn how to handle exceptions in Java using try-catch blocks, multiple catch blocks, exception types, nested try-catch, and practical examples.

Gaurav 6 min read Sign in to save
On this page

Java Try-Catch

The try-catch statement in Java is used to handle exceptions that may occur while a program is running. It allows a program to detect an exception and execute alternative code instead of terminating unexpectedly.

For example, dividing a number by zero causes an ArithmeticException:

int result = 10 / 0;

The operation can be handled using try-catch:

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

Output:

Cannot divide by zero

What Is Try-Catch in Java?

A try block contains code that may throw an exception, while a catch block contains the code used to handle that exception.

Basic syntax:

try {
    // Code that may throw an exception
}
catch (ExceptionType e) {
    // Exception handling code
}

For example:

public class Main {

    public static void main(String[] args) {

        try {
            int result = 10 / 0;
            System.out.println(result);
        }
        catch (ArithmeticException e) {
            System.out.println("Division by zero is not allowed");
        }
    }
}

When the exception occurs, Java stops executing the remaining statements inside the try block and searches for a matching catch block.

How Try-Catch Works

Consider:

try {
    System.out.println("Start");

    int result = 10 / 0;

    System.out.println("End");
}
catch (ArithmeticException e) {
    System.out.println("Exception handled");
}

Output:

Start
Exception handled

The statement:

System.out.println("End");

does not execute because the exception occurs before it.

The execution flow is:

try block
   ↓
Exception occurs
   ↓
Remaining try statements are skipped
   ↓
Matching catch block
   ↓
Program continues

Why Use Try-Catch?

Try-catch is useful when an operation may fail during execution.

Common examples include:

  • Reading files
  • Database operations
  • Network communication
  • Parsing input
  • Array access
  • Arithmetic operations
  • Converting strings to numbers

For example:

String value = "abc";

try {
    int number = Integer.parseInt(value);
}
catch (NumberFormatException e) {
    System.out.println("Invalid number");
}

Output:

Invalid number

Catching an Exception

The catch block specifies the type of exception it can handle.

Example:

try {
    int result = 10 / 0;
}
catch (ArithmeticException e) {
    System.out.println("Arithmetic error occurred");
}

The variable e contains the exception object.

You can use it to get information about the exception.

getMessage()

catch (ArithmeticException e) {
    System.out.println(e.getMessage());
}

For division by zero, the message may be:

/ by zero

printStackTrace()

catch (ArithmeticException e) {
    e.printStackTrace();
}

This prints information about the exception and the call stack, which can be useful during debugging.

Multiple Catch Blocks

A single try block can have multiple catch blocks.

Example:

try {

    int[] numbers = {10, 20, 30};

    System.out.println(numbers[5]);

}
catch (ArithmeticException e) {

    System.out.println("Arithmetic error");

}
catch (ArrayIndexOutOfBoundsException e) {

    System.out.println("Invalid array index");

}
catch (Exception e) {

    System.out.println("Some other exception occurred");
}

The appropriate catch block is selected based on the exception type.

Order of Multiple Catch Blocks

When using multiple catch blocks, more specific exception types must come before more general exception types.

Correct:

try {
    // Code
}
catch (ArrayIndexOutOfBoundsException e) {
    // Specific exception
}
catch (Exception e) {
    // General exception
}

Incorrect:

try {
    // Code
}
catch (Exception e) {
    // General exception
}
catch (ArrayIndexOutOfBoundsException e) {
    // Unreachable
}

The second example causes a compilation error because Exception can already catch ArrayIndexOutOfBoundsException.

Catching the Parent Exception

You can catch a parent exception type when you want to handle multiple related exceptions in the same way.

Example:

try {

    int[] numbers = {10, 20};

    System.out.println(numbers[5]);

}
catch (RuntimeException e) {

    System.out.println("Runtime exception occurred");
}

ArrayIndexOutOfBoundsException is a subclass of RuntimeException, so it can be caught by the parent type.

However, catching a more specific type is often preferable when different exceptions require different handling.

Using finally with Try-Catch

A finally block can be added after try and catch.

It is commonly used for cleanup operations.

Example:

try {

    int result = 10 / 2;
    System.out.println(result);

}
catch (ArithmeticException e) {

    System.out.println("Arithmetic error");

}
finally {

    System.out.println("Operation completed");
}

Output:

5
Operation completed

The finally block generally executes whether an exception occurs or not.

Try-Catch-Finally Syntax

The complete structure is:

try {
    // Risky code
}
catch (ExceptionType e) {
    // Handle exception
}
finally {
    // Cleanup code
}

Example:

try {
    int result = 10 / 0;
}
catch (ArithmeticException e) {
    System.out.println("Cannot divide by zero");
}
finally {
    System.out.println("Finally block executed");
}

Output:

Cannot divide by zero
Finally block executed

Nested Try-Catch

A try-catch block can be placed inside another try block.

Example:

try {

    System.out.println("Outer try");

    try {

        int result = 10 / 0;

    }
    catch (ArithmeticException e) {

        System.out.println("Inner catch");

    }

}
catch (Exception e) {

    System.out.println("Outer catch");
}

Output:

Outer try
Inner catch

The inner catch handles the exception, so it does not propagate to the outer catch.

Try Inside a Catch Block

A try block can also be used inside a catch block when another operation performed during exception handling may itself fail.

Example:

try {

    int result = 10 / 0;

}
catch (ArithmeticException e) {

    System.out.println("Handling arithmetic exception");

    try {

        int number = Integer.parseInt("abc");

    }
    catch (NumberFormatException ex) {

        System.out.println("Invalid number");
    }
}

Nested exception handling should be used only when it makes the error-handling flow clearer.

Multi-Catch

Java allows multiple exception types to be handled using a single catch block with the | operator.

Example:

try {

    // Code that may throw different exceptions

}
catch (IOException | NumberFormatException e) {

    System.out.println("Operation failed");
}

This is useful when the handling logic is identical for both exception types.

The exception types in a multi-catch cannot have a parent-child relationship.

For example, this is invalid:

catch (Exception | IOException e) {
}

because IOException is already a subclass of Exception.

Try-Catch with User Input

Try-catch is frequently used when processing user input.

Example:

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        try {

            System.out.print("Enter a number: ");

            int number = scanner.nextInt();

            System.out.println("You entered: " + number);

        }
        catch (java.util.InputMismatchException e) {

            System.out.println("Please enter a valid integer");
        }
    }
}

If the user enters text instead of an integer, the exception can be handled without abruptly terminating the program.

Try-Catch with Array Access

Array indexes must be within the valid range.

Example:

int[] numbers = {10, 20, 30};

try {

    System.out.println(numbers[5]);

}
catch (ArrayIndexOutOfBoundsException e) {

    System.out.println("Invalid array index");
}

Output:

Invalid array index

The valid indexes are 0, 1, and 2.

Try-Catch with Number Conversion

Converting an invalid string to a number can cause NumberFormatException.

Example:

String value = "100abc";

try {

    int number = Integer.parseInt(value);

    System.out.println(number);

}
catch (NumberFormatException e) {

    System.out.println("The value is not a valid integer");
}

Output:

The value is not a valid integer

Try-Catch with Null Values

Calling an instance method through a null reference can result in NullPointerException.

Example:

String name = null;

try {

    System.out.println(name.length());

}
catch (NullPointerException e) {

    System.out.println("Name cannot be null");
}

Output:

Name cannot be null

However, exception handling should not be used as a substitute for normal null checks or proper program design.

Try-Catch with Methods

A method can contain its own try-catch block.

Example:

class Calculator {

    int divide(int a, int b) {

        try {

            return a / b;

        }
        catch (ArithmeticException e) {

            System.out.println("Cannot divide by zero");

            return 0;
        }
    }
}

Usage:

Calculator calculator = new Calculator();

System.out.println(calculator.divide(10, 0));

Output:

Cannot divide by zero
0

Try-Catch and Exception Propagation

An exception can be propagated to a calling method if it is not handled where it occurs.

Example:

class Main {

    static void method3() {

        int result = 10 / 0;
    }

    static void method2() {

        method3();
    }

    static void method1() {

        method2();
    }

    public static void main(String[] args) {

        try {

            method1();

        }
        catch (ArithmeticException e) {

            System.out.println("Exception handled in main");
        }
    }
}

The exception originates in method3() but is handled in main().

The call flow is:

main()
  ↓
method1()
  ↓
method2()
  ↓
method3()
  ↓
ArithmeticException
  ↓
main() catch block

Try-Catch vs throws

Try-catch handles an exception.

The throws keyword declares that a method may pass an exception to its caller.

Example using try-catch:

void readFile() {

    try {

        // File operation

    }
    catch (IOException e) {

        System.out.println("File error");
    }
}

Example using throws:

void readFile() throws IOException {

    // File operation
}

In the second example, the method does not handle the exception itself. The caller must decide how to handle or propagate it.

Try-Catch vs throw

try-catch is used to handle an exception.

throw is used to explicitly create or propagate an exception.

Example:

try {

    validateAge(15);

}
catch (IllegalArgumentException e) {

    System.out.println(e.getMessage());
}

The method can explicitly throw the exception:

static void validateAge(int age) {

    if (age < 18) {

        throw new IllegalArgumentException(
            "Age must be at least 18"
        );
    }
}

Try-With-Resources

When working with resources such as files or streams, Java provides try-with-resources.

Example:

import java.io.FileReader;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {

        try (FileReader reader = new FileReader("data.txt")) {

            int data = reader.read();

            System.out.println(data);

        }
        catch (IOException e) {

            System.out.println("File operation failed");
        }
    }
}

The FileReader is automatically closed when the try block finishes.

This is generally preferable to manually closing resources in a finally block.

What Happens If No Exception Occurs?

If no exception occurs inside the try block, the statements execute normally and the matching catch block is skipped.

Example:

try {

    int result = 10 / 2;

    System.out.println(result);

}
catch (ArithmeticException e) {

    System.out.println("Exception occurred");
}

Output:

5

The catch block does not execute.

What Happens If an Exception Occurs?

If an exception occurs:

  1. Java stops executing the remaining statements in the try block.
  2. Java searches for a matching catch block.
  3. The matching catch block executes.
  4. Execution continues after the try-catch statement.

Example:

try {

    System.out.println("Before");

    int result = 10 / 0;

    System.out.println("After");

}
catch (ArithmeticException e) {

    System.out.println("Handled");
}

System.out.println("Program continues");

Output:

Before
Handled
Program continues

The "After" statement does not execute.

What Happens If No Catch Matches?

If an exception occurs and none of the available catch blocks can handle it, the exception continues to propagate up the call stack.

Example:

try {

    int result = 10 / 0;

}
catch (NullPointerException e) {

    System.out.println("Null pointer error");
}

The ArithmeticException is not handled by this catch block.

If no higher-level method handles it, the program terminates and Java prints the exception and stack trace.

Best Practices for Try-Catch

Catch Specific Exceptions

Prefer:

catch (NumberFormatException e) {
    System.out.println("Invalid number");
}

instead of unnecessarily catching:

catch (Exception e) {
    System.out.println("Error");
}

Specific exception handling makes the code easier to understand and allows more appropriate recovery.

Keep the Try Block Small

Avoid placing a large amount of unrelated code inside one try block.

Prefer:

try {
    int number = Integer.parseInt(value);
}
catch (NumberFormatException e) {
    System.out.println("Invalid number");
}

rather than wrapping an entire method unnecessarily.

Do Not Ignore Exceptions

Avoid empty catch blocks:

catch (Exception e) {
}

An ignored exception can hide important application problems.

Preserve the Original Cause

When wrapping an exception, preserve the original exception:

catch (IOException e) {

    throw new RuntimeException(
        "Unable to read configuration",
        e
    );
}

This keeps the original cause available for debugging.

Use Try-With-Resources for Resources

For objects implementing AutoCloseable, prefer:

try (FileReader reader = new FileReader("data.txt")) {
    // Use reader
}

This automatically manages resource cleanup.

Common Mistakes

Putting Unrelated Code in the Try Block

Avoid:

try {

    // Database operation
    // Business logic
    // UI logic
    // Logging
    // Other unrelated operations

}
catch (Exception e) {
}

A smaller try block makes it clearer which operation can fail.

Catching the Wrong Exception

For example:

try {

    int result = 10 / 0;

}
catch (IOException e) {

    System.out.println("File error");
}

IOException does not handle ArithmeticException.

Catching a General Exception Before a Specific One

Incorrect:

catch (Exception e) {
}
catch (ArithmeticException e) {
}

Correct:

catch (ArithmeticException e) {
}
catch (Exception e) {
}

Using Exceptions for Normal Control Flow

Exceptions should generally represent exceptional situations rather than ordinary expected branching.

Use normal conditions when an operation can be checked directly.

Key Points to Remember

  • try contains code that may throw an exception.
  • catch handles a matching exception.
  • Multiple catch blocks can handle different exception types.
  • Specific exceptions should generally be caught before general exceptions.
  • finally can be used for cleanup.
  • Try-with-resources automatically closes AutoCloseable resources.
  • An exception stops the remaining statements in the current try block.
  • If no matching catch exists, the exception propagates to the caller.
  • throw explicitly throws an exception.
  • throws declares exceptions that a method may propagate.
  • Multi-catch allows multiple exception types to share one handler.
  • Empty catch blocks should generally be avoided.
  • Catching specific exceptions usually makes error handling clearer.

Conclusion

The try-catch statement in Java provides a structured way to handle exceptions and keep applications from terminating unexpectedly when recoverable runtime problems occur.

Use try for operations that may fail, catch for handling specific exceptions, and finally when cleanup is required. For resources such as files and streams, prefer try-with-resources.

Good exception handling should make failures clear, preserve useful diagnostic information, and allow the application to recover or fail gracefully when appropriate.

Related

Found a problem on this page, or something that could be clearer?

Goes straight to the author. Not published anywhere.