Topic 80 of 119 8. Exception Handling in Java Interactive Tutorial

Java try-catch Block: Catching and Handling Runtime Exceptions

10 mins read Last updated: 22 Aug 2026 28,840 views

Direct Answer & Core Concept

Java programs can sometimes encounter problems while they are running. For example, a program may try to divide a number by zero, access an invalid array position, or convert invalid text into a number.

Instead of allowing these problems to immediately terminate the program, Java provides the try-catch block. It allows developers to place risky code inside try and define how an exception should be handled inside catch.

Understanding try-catch is one of the most important steps toward writing reliable and user-friendly Java applications.

Detailed Explanation & Mechanics

What Is a try-catch Block in Java?

A try-catch block is a Java exception-handling mechanism used to detect and handle exceptions that occur while a program is executing.

The code that may cause an exception is placed inside the try block. If an exception occurs, Java searches for a matching catch block and executes its handling code.

Basic syntax

Main.java
Run Online
try {
    // Code that may throw an exception
} catch (ExceptionType e) {
    // Code that handles the exception
}

For example:

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

Output:

The exception is handled instead of allowing the program to terminate at that point.


Why Do We Need try-catch?

Without exception handling, an unexpected runtime problem can stop normal program execution.

Consider:

Main.java
Run Online
public class Main {
    public static void main(String[] args) {
        int number = 10 / 0;
        System.out.println("Program continues...");
    }
}

This causes an ArithmeticException.

The statement after the exception is not executed.

With try-catch:

Main.java
Run Online
public class Main {
    public static void main(String[] args) {
        try {
            int number = 10 / 0;
        } catch (ArithmeticException e) {
            System.out.println("Cannot divide by zero.");
        } System.out.println("Program continues...");
    }
}

Output:

Main.java
Run Online
Cannot divide by zero.Program continues...

The catch block handles the exception and allows execution to continue after the exception-handling structure.


Understanding Runtime Exceptions

A runtime exception occurs while a Java program is executing.

Most runtime exceptions are subclasses of RuntimeException. They are also known as unchecked exceptions because Java does not require the compiler to force the programmer to catch or declare them.

Common examples include:

  • ArithmeticException

  • NullPointerException

  • ArrayIndexOutOfBoundsException

  • NumberFormatException

  • IllegalArgumentException

  • ClassCastException


Handling ArithmeticException

ArithmeticException can occur when an invalid arithmetic operation is performed.

A common example is integer division by zero.

Main.java
Run Online
public class Main {
    public static void main(String[] args) {
        try {
            int result = 20 / 0;
            System.out.println(result);
        } catch (ArithmeticException e) {
            System.out.println("Division by zero is not allowed.");
        }
    }
}

Output:

Main.java
Run Online
Division by zero is not allowed.

The exception type in the catch block matches the exception generated by the code inside try.


Handling NumberFormatException

NumberFormatException occurs when Java cannot convert a string into a valid numeric value.

For example:

Main.java
Run Online
public class Main {
    public static void main(String[] args) {
        try {
            int number = Integer.parseInt("Hello");
            System.out.println(number);
        } catch (NumberFormatException e) {
            System.out.println("Invalid number format.");
        }
    }
}

Output:

This is useful when processing values entered by users.


Handling ArrayIndexOutOfBoundsException

An ArrayIndexOutOfBoundsException can occur when a program tries to access an array position outside its valid range.

Main.java
Run Online
public class Main {
    public static void main(String[] args) {
        int[] numbers = {
            10, 20, 30
        };
        try {
            System.out.println(numbers[5]);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Invalid array index.");
        }
    }
}

Output:

The valid indexes in this array are 0, 1, and 2.


Handling NullPointerException

A NullPointerException can occur when code tries to use an object reference whose value is null.

Main.java
Run Online
public class Main {
    public static void main(String[] args) {
        String name = null;
        try {
            System.out.println(name.length());
        } catch (NullPointerException e) {
            System.out.println("The string is null.");
        }
    }
}

Output:

Although try-catch can handle this exception, it is often better to prevent the null situation through proper validation and program design.


How Java Executes a try-catch Block

Consider:

Main.java
Run Online
try {
    System.out.println("Step 1");
    int result = 10 / 0;
    System.out.println("Step 2");
} catch (ArithmeticException e) {
    System.out.println("Exception handled");
}System.out.println("Step 3");

Output:

Main.java
Run Online
Step 1Exception handledStep 3

The execution flow is:

  1. Java enters the try block.

  2. "Step 1" is printed.

  3. Division by zero causes an ArithmeticException.

  4. The remaining statements in the try block are skipped.

  5. Java searches for a matching catch block.

  6. The catch block executes.

  7. Execution continues after the complete try-catch structure.

This execution flow is important when debugging exception-related problems.


What Happens to Code After an Exception?

Once an exception occurs inside a try block, Java does not continue executing the remaining statements in that try block.

Example:

Main.java
Run Online
try {
    System.out.println("A");
    int result = 10 / 0;
    System.out.println("B");
} catch (ArithmeticException e) {
    System.out.println("C");
}System.out.println("D");

Output:

B is not printed because the exception occurs before that statement.


Catching the Exception Object

The catch block can receive an exception object.

Main.java
Run Online
try {
    int result = 10 / 0;
} catch (ArithmeticException e) {
    System.out.println(e);
}

A typical output is:

Main.java
Run Online
java.lang.ArithmeticException: / by zero

The variable e contains information about the exception.


getMessage() Method

The getMessage() method returns the message associated with an exception.

Main.java
Run Online
try {
    int result = 10 / 0;
} catch (ArithmeticException e) {
    System.out.println(e.getMessage());
}

Typical output:

This can be useful when logging or displaying technical information.


printStackTrace() Method

The printStackTrace() method prints information about where the exception occurred.

Main.java
Run Online
try {
    int result = 10 / 0;
} catch (ArithmeticException e) {
    e.printStackTrace();
}

It can help developers identify the source of an exception during debugging.

However, directly showing stack traces to end users is usually inappropriate. Production applications should generally log technical details and show users a clear, safe message.


Catching a General Exception

Java allows you to catch a broader exception type.

Main.java
Run Online
try {
    int result = 10 / 0;
} catch (Exception e) {
    System.out.println("An error occurred.");
}

Because ArithmeticException is a subclass of RuntimeException, and RuntimeException is a subclass of Exception, this catch block can handle it.

However, catching Exception everywhere is generally not a good practice.

Prefer the most specific exception type that you can reasonably handle.

For example:

Main.java
Run Online
catch (ArithmeticException e)

is usually more informative than:


Specific Exception vs General Exception

Consider these two approaches.

Specific exception

Main.java
Run Online
try {
    int result = 10 / 0;
} catch (ArithmeticException e) {
    System.out.println("Invalid arithmetic operation.");
}

General exception

Main.java
Run Online
try {
    int result = 10 / 0;
} catch (Exception e) {
    System.out.println("Something went wrong.");
}

The first version communicates exactly what kind of problem the application expects to handle.

The second version may hide programming errors or unexpected problems.

As a general rule:

Catch the most specific exception that you can meaningfully handle.


Multiple catch Blocks

A single try block can have multiple catch blocks.

Main.java
Run Online
try {
    String value = "abc";
    int number = Integer.parseInt(value);
    int result = 10 / 0;
} catch (NumberFormatException e) {
    System.out.println("Invalid number.");
} catch (ArithmeticException e) {
    System.out.println("Cannot divide by zero.");
}

Java checks the catch blocks for a compatible exception type.

This allows different problems to receive different handling.


Order of Multiple catch Blocks

When multiple catch blocks are used, more specific exception types must appear before broader exception types.

Correct:

Main.java
Run Online
try {
    int number = Integer.parseInt("abc");
} catch (NumberFormatException e) {
    System.out.println("Invalid number.");
} catch (RuntimeException e) {
    System.out.println("Runtime error.");
}

NumberFormatException is more specific than RuntimeException.

An overly broad catch placed first can make a later specific catch unreachable.

For example, this is incorrect:

Main.java
Run Online
try {
    int number = Integer.parseInt("abc");
} catch (RuntimeException e) {
    System.out.println("Runtime error.");
} catch (NumberFormatException e) {
    System.out.println("Invalid number.");
}

The second catch cannot be reached because RuntimeException already catches NumberFormatException.


Multi-Catch with One catch Block

Java also supports handling multiple unrelated exception types with a single catch block.

Main.java
Run Online
try {
    // Risky code
} catch (ArithmeticException | NumberFormatException e) {
    System.out.println("Invalid input or arithmetic operation.");
}

This is useful when different exceptions require the same handling logic.

The exceptions listed in a multi-catch cannot have a parent-child relationship with each other.


try-catch with User Input

A common real-world use of try-catch is handling invalid user input.

Main.java
Run Online
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter a number: ");
        try {
            int number = scanner.nextInt();
            System.out.println("You entered: " + number);
        } catch (Exception e) {
            System.out.println("Please enter a valid integer.");
        } scanner.close();
    }
}

If the user enters:

the program prints:

If the user enters:

the program can handle the invalid input instead of terminating unexpectedly.

For production code, it is often preferable to catch the specific exception expected from the input operation rather than catching Exception broadly.


try-catch Does Not Fix the Original Problem

It is important to understand that try-catch does not magically correct faulty code.

For example:

Main.java
Run Online
try {
    int result = 10 / 0;
} catch (ArithmeticException e) {
    System.out.println("Error handled.");
}

The division by zero still occurred.

The catch block simply provides a defined response to the exception.

A good exception-handling strategy should consider whether the problem should be:

  • corrected,

  • retried,

  • reported,

  • logged,

  • converted into another exception,

  • or safely communicated to the user.


Nested try-catch Blocks

A try-catch block can exist inside another try block.

Main.java
Run Online
try {
    try {
        int result = 10 / 0;
    } catch (ArithmeticException e) {
        System.out.println("Inner exception handled.");
    } System.out.println("Outer try continues.");
} catch (Exception e) {
    System.out.println("Outer exception handled.");
}

Nested exception handling is possible, but excessive nesting can make code difficult to understand.

Prefer simpler structures when possible.


try-catch and Method Calls

An exception can occur inside a method called from a try block.

Main.java
Run Online
public class Main {
    static void calculate() {
        int result = 10 / 0;
    } public static void main(String[] args) {
        try {
            calculate();
        } catch (ArithmeticException e) {
            System.out.println("Calculation failed.");
        }
    }
}

Output:

The exception travels back through the method call until Java finds a matching handler.

This behavior is known as exception propagation.


try-catch and RuntimeException

Runtime exceptions are unchecked exceptions.

For example:

Main.java
Run Online
public class Main {
    public static void main(String[] args) {
        try {
            String text = null;
            System.out.println(text.length());
        } catch (RuntimeException e) {
            System.out.println("Runtime exception handled.");
        }
    }
}

Output:

Main.java
Run Online
Runtime exception handled.

However, catching RuntimeException broadly can hide different types of programming errors.

In most cases, catching the specific expected exception is better.


When Should You Use try-catch?

Use try-catch when an operation can reasonably fail and your program has a meaningful way to handle that failure.

Common situations include:

  • Parsing user input

  • Converting strings to numbers

  • Reading files

  • Database operations

  • Network communication

  • Calling external services

  • Processing user-provided data

  • Working with APIs

  • Handling expected runtime failures

For example:

Main.java
Run Online
try {
    int age = Integer.parseInt(input);
} catch (NumberFormatException e) {
    System.out.println("Please enter a valid age.");
}

This provides a useful response to invalid input.


When Should You Avoid try-catch?

Do not surround every line of code with try-catch.

This can make programs difficult to read and can hide real programming problems.

Avoid patterns like:

Main.java
Run Online
try {
    // Almost the entire application
} catch (Exception e) {
    // Ignore everything
}

This approach makes debugging harder because unexpected errors can disappear without proper investigation.

Instead, place the try block around the operation that you actually expect may fail.


Empty catch Blocks Are Dangerous

Avoid silently ignoring exceptions.

Bad example:

Main.java
Run Online
try {
    int result = 10 / 0;
} catch (ArithmeticException e) {
}

The program catches the exception but provides no response or useful diagnostic information.

A better approach might be:

Main.java
Run Online
try {
    int result = 10 / 0;
} catch (ArithmeticException e) {
    System.out.println("Unable to perform the calculation.");
}

For application code, logging may also be appropriate depending on the situation.


Do Not Use Exceptions as Normal Program Flow

Exceptions are designed to represent exceptional conditions, not ordinary decisions.

Avoid code like:

Main.java
Run Online
try {
    int number = Integer.parseInt(input);
} catch (NumberFormatException e) {
    // Used as normal validation for every possible input
}

For input validation, depending on the situation, explicit validation can sometimes be clearer.

However, parsing APIs may naturally communicate invalid input through exceptions, so using a targeted catch can still be appropriate.

The key is to use exceptions deliberately rather than making them the normal control mechanism for every decision.


Best Practices for try-catch

1. Catch Specific Exceptions

Prefer:

Main.java
Run Online
catch (NumberFormatException e)

over:

when you know exactly what failure you are handling.


2. Keep the try Block Small

Instead of:

Main.java
Run Online
try {
    // Hundreds of lines of code
}

keep the block focused:

Main.java
Run Online
try {
    int number = Integer.parseInt(input);
} catch (NumberFormatException e) {
    System.out.println("Invalid number.");
}

A small try block makes it easier to understand which operation caused the exception.


3. Give Users Useful Messages

Technical exception messages are not always suitable for users.

Instead of:

Main.java
Run Online
java.lang.NumberFormatException: For input string: "abc"

a user-facing application might display:

Main.java
Run Online
Please enter a valid number.

4. Log Technical Details When Appropriate

For server-side applications, developers may need the original exception details for troubleshooting.

For example:

Main.java
Run Online
catch (NumberFormatException e) {
    // Log exception details
    System.out.println("Invalid numeric input.");
}

The exact logging approach depends on the application and logging framework.


5. Do Not Swallow Exceptions

If an exception matters, do not silently ignore it.

A useful handler should either:

  • recover from the problem,

  • provide an appropriate response,

  • log the problem,

  • rethrow it,

  • or otherwise preserve the failure information.


6. Avoid Overly Broad Catch Blocks

This:

can be useful at carefully chosen boundaries, but it should not become the default solution everywhere.

Specific catches make application behavior clearer.


Common Mistakes with try-catch

Mistake 1: Catching the Wrong Exception

Main.java
Run Online
try {
    int result = 10 / 0;
} catch (NullPointerException e) {
    System.out.println("Error");
}

This does not handle the ArithmeticException.

The catch type must be compatible with the exception that occurs.


Mistake 2: Catching Everything

This is generally too broad for normal application exception handling because Throwable also includes serious Error conditions.

Usually, application code should catch specific exceptions that it can actually handle.


Mistake 3: Empty catch Block

This hides failures and makes troubleshooting difficult.


Mistake 4: Huge try Block

Putting an entire application inside one try block makes it difficult to determine which operation failed.

Keep exception boundaries focused.


Mistake 5: Exposing Technical Details to Users

Avoid directly displaying full stack traces to normal users.

Use clear messages for users and preserve technical details through appropriate logging.


Real-World Example: Safe Number Conversion

Suppose an application receives a number as text.

Main.java
Run Online
public class Main {
    static int convertToNumber(String value) {
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            return -1;
        }
    } public static void main(String[] args) {
        int number = convertToNumber("250");
        if (number != -1) {
            System.out.println("Number: " + number);
        } else {
            System.out.println("Invalid number.");
        }
    }
}

Output:

The try-catch is placed close to the operation that can actually fail.


Another Real-World Example

Consider processing a list of numeric strings:

Main.java
Run Online
public class Main {
    public static void main(String[] args) {
        String[] values = {
            "10", "20", "abc", "40"
        };
        for (String value : values) {
            try {
                int number = Integer.parseInt(value);
                System.out.println("Number: " + number);
            } catch (NumberFormatException e) {
                System.out.println("Invalid value: " + value);
            }
        }
    }
}

Output:

Main.java
Run Online
Number: 10Number: 20Invalid value: abcNumber: 40

Here, one invalid value does not necessarily prevent the loop from processing the later values.

This demonstrates an important benefit of localized exception handling.


try-catch vs if-else

if-else and try-catch serve different purposes.

Use if-else for normal conditions:

Main.java
Run Online
if (age >= 18) {
    System.out.println("Adult");
} else {
    System.out.println("Minor");
}

Use try-catch when an operation can produce an exception:

Main.java
Run Online
try {
    int number = Integer.parseInt(input);
} catch (NumberFormatException e) {
    System.out.println("Invalid number.");
}

Good Java programs use both appropriately.


Key Difference Between Error and Exception Handling

Java's throwable hierarchy includes both Error and Exception.

Architecture Diagram
Throwable
├── Error
└── Exception
    └── RuntimeException

Runtime exceptions such as NullPointerException, ArithmeticException, and NumberFormatException are normally application-level conditions that can sometimes be handled.

Error generally represents serious conditions that application code typically should not try to recover from.

Therefore, normal try-catch code should generally target the exceptions that the application can meaningfully handle.


Quick Example

Here is the simplest form to remember:

Main.java
Run Online
public class Main {
    public static void main(String[] args) {
        try {
            int result = 100 / 0;
            System.out.println(result);
        } catch (ArithmeticException e) {
            System.out.println("Cannot divide by zero.");
        }
    }
}

The basic pattern is:

Main.java
Run Online
try↓Risky operation↓Exception?↓Yes↓Matching catch↓Handle the problem↓Continue after try-catch

Frequently Asked Questions

What is a try-catch block in Java?

A try-catch block is used to handle exceptions that may occur during program execution. Risky code goes inside try, while the corresponding handling code goes inside catch.

Can try-catch handle runtime exceptions?

Yes. Runtime exceptions such as ArithmeticException, NullPointerException, and NumberFormatException can be handled using try-catch.

What happens when an exception occurs inside try?

Java stops executing the remaining statements in that try block and searches for a compatible catch block.

Can one try block have multiple catch blocks?

Yes. Multiple catch blocks can handle different exception types.

Which catch block should come first?

More specific exception types should come before broader parent exception types.

Should I always catch Exception?

No. When possible, catch the specific exception that you can meaningfully handle.

What is the difference between try and catch?

try contains code that may throw an exception. catch contains code that handles a matching exception.

Does catch fix the exception?

No. The catch block handles the failure; it does not necessarily correct the underlying cause.

Can I use try without catch?

Yes, a try statement can be used with finally instead of catch. However, a standalone try must be completed with an appropriate catch, finally, or both.

Quick Revision

Quick Revision

ConceptMeaning
tryContains code that may throw an exception
catchHandles a matching exception
ArithmeticExceptionCommon arithmetic runtime exception
NumberFormatExceptionInvalid string-to-number conversion
NullPointerExceptionInvalid use of a null reference
ArrayIndexOutOfBoundsExceptionInvalid array index
RuntimeExceptionParent class for many unchecked exceptions
Multiple catchHandles different exception types
Multi-catchHandles multiple types with one catch
getMessage()Gets an exception message
printStackTrace()Prints exception diagnostic information

Graphics and Design Ideas

Graphic 1 — try-catch Flow

Create a simple flow diagram:

Architecture Diagram
┌─────────────┐
│ try block   │
│ Risky code  │
└──────┬──────┘
       │
       ▼
  Exception?
    /     \
  No       Yes
  │         │
  ▼         ▼
Continue   catch
             │
             ▼
       Handle exception

Graphic 2 — Runtime Exception Examples

Use a visual card containing:

Architecture Diagram
RuntimeException
       │
       ├── ArithmeticException
       ├── NullPointerException
       ├── NumberFormatException
       ├── ArrayIndexOutOfBoundsException
       └── IllegalArgumentException

Graphic 3 — Multiple Catch

Show:

Architecture Diagram
                 try
                  │
        ┌─────────┴─────────┐
        ▼                   ▼
NumberFormatException  ArithmeticException
        │                   │
        ▼                   ▼
  Handle input          Handle arithmetic

These visuals can make the page easier for beginners to understand and can also improve the instructional structure of the tutorial.

Runnable Code Example: Java try-catch Block

Java 17+
Main.java
Run Online
public class TryCatchDemo {
    public static void main(String[] args) {
        try {
            String text = null;
            System.out.println(text.length());
            // Throws NullPointerException
        } catch (NullPointerException e) {
            System.err.println("Null reference encountered: " + e.getMessage());
        } catch (Exception e) {
            System.err.println("General exception caught");
        }
    }
}

Common Java Technical Interview Questions & Answers

Interview Prep
Q1

Why must specific catch blocks precede general catch blocks?

Because Java evaluates catch blocks in top-to-bottom order; placing a general Exception first would make subsequent specific catches unreachable compile errors.
Q2

Are variables declared inside a try block accessible in the catch block?

No, variables declared inside try are locally scoped to that block only.

Key Takeaways, Best Practices & Clean Code Rules

Java Best Practice & Production Rules

Log exceptions with their full stack trace (e.g. logger.error("Context", e)) rather than just printing e.getMessage() to aid debugging.