try / catch / finally
The try/catch statement lets you intercept an exception instead of letting it crash the program. Code that might fail goes inside the try block; code that handles the failure goes inside a matching catch block.
Basic Syntax
A basic try/catch
Java
public class BasicTryCatchDemo {
public static void main(String[] args) {
try {
int result = 10 / 0;
System.out.println(result);
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero: " + e.getMessage());
}
System.out.println("Program continues normally");
}
}Cannot divide by zero: / by zero Program continues normally
Because the exception was caught, the program did not crash — it printed a friendly message and moved on to the next statement.
Multiple catch Blocks
You can stack several catch blocks after one try to handle different exception types differently. Java checks them in order and runs the first one that matches.
Handling different failures differently
Java
public class MultipleCatchDemo {
public static void main(String[] args) {
int[] numbers = {1, 2, 3};
try {
System.out.println(numbers[10]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Bad index: " + e.getMessage());
} catch (NullPointerException e) {
System.out.println("Null reference: " + e.getMessage());
} catch (Exception e) {
System.out.println("Something else went wrong: " + e);
}
}
}Warning
Order matters: more specific exception types must be caught before more general ones. Placing catch (Exception e) first would swallow every exception, making the more specific catch blocks below it unreachable — and would actually fail to compile in Java, which detects unreachable catch blocks.
Multi-Catch (Java 7+)
When two or more exception types should be handled identically, you can combine them into a single catch clause with a pipe (|), avoiding duplicated handler code.
Multi-catch
Java
import java.io.IOException;
import java.sql.SQLException;
public class MultiCatchDemo {
public static void main(String[] args) {
try {
riskyOperation();
} catch (IOException | SQLException e) {
System.out.println("Operation failed: " + e.getMessage());
}
}
static void riskyOperation() throws IOException, SQLException {
throw new IOException("disk unavailable");
}
}The finally Block
A finally block runs after the try/catch, guaranteed, whether or not an exception was thrown, and whether or not it was caught. It is the standard place for cleanup code — closing a file, releasing a lock, disconnecting from a database.
finally always runs
Java
public class FinallyDemo {
public static void main(String[] args) {
try {
System.out.println("Trying...");
throw new RuntimeException("boom");
} catch (RuntimeException e) {
System.out.println("Caught: " + e.getMessage());
} finally {
System.out.println("Cleanup runs no matter what");
}
}
}Trying... Caught: boom Cleanup runs no matter what
Note
finally even runs when the try or catch block contains a return statement — a genuinely surprising detail that shows up often in interview questions. The method does not actually return until the finally block has finished executing.
finally runs even with a return in try
Java
public class FinallyWithReturnDemo {
public static void main(String[] args) {
System.out.println(getValue());
}
static int getValue() {
try {
return 1;
} finally {
System.out.println("finally runs before the method actually returns");
}
}
}finally runs before the method actually returns 1
Warning
Never return from inside a finally block. If you do, it silently overrides any value or exception that the try or catch block was about to produce, which is a classic and very confusing bug.
Tip
A good mental model: try is "attempt this," catch is "if it fails this specific way, do this instead," and finally is "no matter what happened above, always do this before moving on."