Skip to main content

Try, Catch, and Finally

Java uses five keywords for exception handling: try, catch, finally, throw, and throws. This section covers the first three, which are used to build the core mechanism of handling exceptions.


1. The try Block

The try block contains the code that might generate an exception. You must place suspicious code (code that can throw an exception) inside a try block.

  • A try block must be followed by either a catch block or a finally block (or both).
  • You cannot have a standalone try block.

2. The catch Block

The catch block is used to handle the exception. It must be preceded by a try block.

  • The catch block takes a parameter that matches the type of exception it can handle.
  • If an exception occurs in the try block, the rest of the code in the try block is skipped, and the JVM jumps to the appropriate catch block.

Example: Basic Try-Catch

public class LabException1 {

public static void main(String args[]) {
System.out.println("Program Started");

try {
int result = 10 / 0; // This will throw an ArithmeticException
System.out.println("Result: " + result); // This line is skipped
} catch (ArithmeticException e) {
System.out.println("Exception caught: Cannot divide by zero!");
}

System.out.println("Program Ended Normaly");
}
}

Output:

Program Started
Exception caught: Cannot divide by zero!
Program Ended Normaly

[!NOTE] Because we handled the exception, the program didn't crash and "Program Ended Normally" was printed successfully.


3. Multiple catch Blocks

A single try block can be followed by multiple catch blocks to handle different types of exceptions in different ways.

  • Rule of Ordering: When using multiple catch blocks, the catch block for the subclass exception must appear before the catch block for the superclass exception. Otherwise, you will get a compile-time error.

Example: Multiple Catch

public class LabException2 {

public static void main(String args[]) {
try {
int[] numbers = { 1, 2, 3 };
int result = numbers[5] / 0;
} catch (ArithmeticException e) {
System.out.println("Arithmetic Exception occurred");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Array Index Out Of Bounds Exception occurred");
} catch (Exception e) {
System.out.println("Some general exception occurred");
}
}
}

[!WARNING] If you put catch (Exception e) at the very top, the subsequent catch blocks will become unreachable code, resulting in a compile-time error.


4. The finally Block

The finally block is used to execute crucial code, such as closing connections, closing files, or releasing resources.

  • The finally block always executes, regardless of whether an exception was thrown or caught.
  • It is placed after the try block and all catch blocks.

Example: Using Finally

public class LabException3 {

public static void main(String args[]) {
try {
System.out.println("Inside try block");
int result = 10 / 2;
} catch (ArithmeticException e) {
System.out.println("Inside catch block");
} finally {
System.out.println("Inside finally block - always executes");
}
}
}

Output:

Inside try block
Inside finally block - always executes

When does finally NOT execute?

There is only one main scenario where a finally block will not execute: if the program is forcefully terminated using System.exit(0) inside the try or catch block.


5. Nested Try-Catch

You can place a try-catch block inside another try block. This is called nested try-catch. It is useful when a specific block of code within a try block can cause a completely different exception.

public class LabException4 {

public static void main(String args[]) {
try {
System.out.println("Outer try block");

try {
System.out.println("Inner try block");
int res = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("Handled Inner ArithmeticException");
}
} catch (Exception e) {
System.out.println("Handled Outer Exception");
}
}
}