Exception Handling
An exception is an unexpected event that disrupts the normal flow of a program. Java uses the try-catch-finally mechanism to handle exceptions. Checked exceptions (which must be handled or declared) differ from unchecked exceptions (runtime exceptions) that are optional to handle.
The Java exception hierarchy: Throwable → Error (system errors, do not handle) and Exception → Checked Exception (IOException, etc.) and RuntimeException (NullPointerException, ArrayIndexOutOfBoundsException, etc.).
Java 7+ supports multi-catch blocks in a single statement. Try-with-resources (Java 7+) automatically closes resources that implement AutoCloseable. Text blocks and switch expressions (Java 14+) also support yield for displaying error messages more elegantly.
Types of Exceptions:
| Category | Examples | Must Handle? |
|---|---|---|
| Checked | IOException, SQLException |
Yes (try-catch or throws) |
| Unchecked | NullPointerException, IllegalArgumentException |
Optional |
| Error | OutOfMemoryError, StackOverflowError |
No (fatal) |
Code Example
import java.io.*;
import java.util.Scanner;
public class PenangananEksepsi {
// Checked exceptions must be declared
static int bagi(int a, int b) throws ArithmeticException {
if (b == 0) throw new ArithmeticException("Cannot divide by zero!");
return a / b;
}
public static void main(String[] args) {
// Try-catch-finally
Scanner sc = new Scanner(System.in);
try {
System.out.print("Enter numerator: ");
int a = sc.nextInt();
System.out.print("Enter denominator: ");
int b = sc.nextInt();
int result = bagi(a, b);
System.out.println("Result: " + result);
} catch (ArithmeticException e) {
System.err.println("Error aritmatika: " + e.getMessage());
} catch (Exception e) {
System.err.println("Error umum: " + e.getMessage());
} finally {
System.out.println("Program done.");
sc.close();
}
// Multi-catch (Java 7+)
try {
String[] arr = {"a", "b"};
System.out.println(arr[5]);
} catch (ArrayIndexOutOfBoundsException | NullPointerException e) {
System.err.println("Array error: " + e.getMessage());
}
// Try-with-resources (Java 7+)
try (BufferedReader br = new BufferedReader(
new FileReader("data.txt"))) {
String line = br.readLine();
System.out.println(line);
} catch (FileNotFoundException e) {
System.err.println("File not found");
} catch (IOException e) {
System.err.println("Read failed: " + e.getMessage());
}
}
}
Code Explanation
- Throw:
throw new ArithmeticException(...)manually throws an exception with an error message. - Throws:
throws ArithmeticExceptionin a method signature tells the caller that this method can throw an exception. - Multi-catch:
catch (A | B e)handles two exception types in a single block — efficient when the handling is the same. - Try-with-resources: resources inside
try(...)are closed automatically after the block finishes, even if an exception occurs — no manual finally needed. - Finally: always runs regardless of exceptions — suitable for cleanup such as closing a scanner or a connection.
Everyday Example
A configuration file reader program with robust error handling:
import java.nio.file.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class ConfigLoader {
public static void main(String[] args) {
Map<String, String> config = loadConfig("config.txt");
if (config.isEmpty()) {
System.out.println("Using default config");
} else {
System.out.println("Config loaded: " + config);
}
}
static Map<String, String> loadConfig(String filename) {
Map<String, String> config = new HashMap<>();
try {
var path = Path.of(filename);
if (!Files.exists(path)) {
System.out.println("File " + filename + " not found");
return config;
}
for (String line : Files.readAllLines(path)) {
if (line.isBlank() || line.startsWith("#")) continue;
String[] part = line.split("=", 2);
if (part.length == 2) {
config.put(part[0].trim(), part[1].trim());
}
}
} catch (IOException e) {
System.err.println("Failed to read config: " + e.getMessage());
}
return config;
}
}
Summary
Good exception handling is what separates robust programs from error-prone ones. Use try-with-resources for resource management, multi-catch for compact handling, and always provide informative error messages. Never handle Errors (OutOfMemoryError, etc.) — those are system issues, not program issues.