Question
Java Multi-Catch: Catch Multiple Exceptions in One Catch Clause
Question
In Java, how can I catch IllegalArgumentException, SecurityException, IllegalAccessException, and NoSuchFieldException in a single catch clause so that the same code runs for each exception?
try {
// Code that may throw exceptions
} catch (/* catch all four exception types here */) {
someCode();
}
How can this be written without repeating someCode() in separate catch blocks?
Short Answer
You will learn how to use Java's multi-catch syntax to handle several exception types with one catch block. You will also learn the important rules: use | between exception types, do not include a subclass and its superclass together, and remember that the caught exception variable is effectively final.
Concept
Java exceptions let a program respond to unusual or failed situations without crashing unexpectedly. A try block contains code that may fail, while a catch block specifies what to do when a particular exception is thrown.
When multiple exception types need exactly the same handling, Java provides multi-catch, available since Java 7. Rather than writing several identical catch blocks, list exception types separated by the pipe character (|).
catch (ExceptionTypeA | ExceptionTypeB exception) {
// Shared recovery or reporting code
}
For the exceptions in the question:
try {
// Code that may throw these exceptions
} catch (IllegalArgumentException | SecurityException |
IllegalAccessException | NoSuchFieldException e) {
someCode();
}
This reduces duplication and makes it clear that all listed failures receive the same treatment.
Multi-catch is appropriate only when the response is truly shared. If each exception needs a different message, recovery action, or return value, separate catch blocks are usually clearer.
Mental Model
Think of a catch block as a service desk for errors.
- Separate
catchblocks are separate service desks: one for each kind of problem. - A multi-catch block is one shared service desk with several signs above it: “We handle
IllegalArgumentException,SecurityException,IllegalAccessException, andNoSuchFieldException.”
Any of those listed exceptions can arrive at the same desk, and the same process, someCode(), is used for all of them.
Syntax and Examples
Use | between exception class names, then declare one exception variable after the final type.
try {
String text = null;
System.out.println(text.length());
} catch (NullPointerException | IllegalArgumentException e) {
System.out.println("The input could not be processed.");
}
If text.length() throws a NullPointerException, Java enters the shared catch block.
For the original set of exceptions:
try {
Class<?> type = Class.forName("example.User");
type.getDeclaredField("id");
} catch (IllegalArgumentException | SecurityException |
IllegalAccessException | NoSuchFieldException e) {
someCode();
}
The exception variable e refers to whichever exception was actually thrown. You can log it or inspect common methods inherited from Throwable:
try {
performReflection();
} catch (IllegalAccessException | NoSuchFieldException e) {
System.err.println( + e.getMessage());
}
Step by Step Execution
Consider this example:
public class MultiCatchDemo {
public static void main(String[] args) {
try {
int age = Integer.parseInt("not-a-number");
System.out.println(age);
} catch (NumberFormatException | SecurityException e) {
System.out.println("Could not read the age.");
System.out.println("Reason: " + e.getClass().getSimpleName());
}
}
}
Execution proceeds as follows:
- Java enters the
tryblock. Integer.parseInt("not-a-number")cannot convert the text to an integer.- It throws a
NumberFormatException. - Java checks whether the exception matches either type in the multi-catch.
NumberFormatExceptionis listed, so Java enters thecatchblock.- The first
printlndisplaysCould not read the age. e.getClass().getSimpleName()identifies the actual exception type and displays .
Real World Use Cases
Multi-catch is useful when different failures have one safe, consistent response.
- Reflection utilities: Handle
NoSuchFieldExceptionandIllegalAccessExceptionby reporting that metadata could not be read. - File and parsing tasks: Handle several input-related exceptions by showing one “invalid import file” message.
- Configuration loading: Treat several validation failures as an invalid configuration and use defaults.
- API boundaries: Convert a small group of low-level exceptions into one application-level error response.
- Command-line tools: Print a single failure message and return a nonzero exit code for related errors.
Example: a configuration reader may reject malformed values and missing required access in the same way.
try {
loadConfiguration();
} catch (IllegalArgumentException | SecurityException e) {
System.err.println("Configuration could not be loaded.");
useDefaultConfiguration();
}
Real Codebase Usage
In real projects, multi-catch is commonly used at a boundary where several technical failures lead to the same business decision.
Log once and fail safely
public UserProfile readProfile(Class<?> type) {
try {
return readProfileWithReflection(type);
} catch (IllegalAccessException | NoSuchFieldException e) {
logger.warn("Profile metadata could not be read for {}", type.getName(), e);
return UserProfile.empty();
}
}
Validate early with guard clauses
Use validation before risky code when possible. This produces more precise errors and reduces exceptions used for normal control flow.
public void updateEmail(String email) {
if (email == null || email.isBlank()) {
throw new IllegalArgumentException("Email is required");
}
saveEmail(email);
}
Preserve different handling when it matters
If one exception requires a retry but another requires a user-facing validation message, do not combine them merely to make the code shorter.
try {
saveRecord(record);
} catch (SecurityException e) {
showPermissionMessage();
} (IllegalArgumentException e) {
showValidationMessage();
}
Common Mistakes
Including a subclass and its superclass
Java rejects a multi-catch where one listed type is a subtype of another. IllegalArgumentException is a subclass of RuntimeException.
// Does not compile
try {
runTask();
} catch (RuntimeException | IllegalArgumentException e) {
System.out.println(e.getMessage());
}
RuntimeException already catches IllegalArgumentException, so the second type would be redundant. Catch only the superclass, or catch the specific types separately when behavior differs.
try {
runTask();
} catch (RuntimeException e) {
System.out.println(e.getMessage());
}
Reassigning the multi-catch variable
A multi-catch variable is implicitly final and cannot be reassigned.
// Does not compile
try {
runTask();
} catch (IllegalArgumentException | SecurityException e) {
e = new IllegalArgumentException("replacement");
}
Instead, create a separate variable if you need one:
{
runTask();
} (IllegalArgumentException | SecurityException e) {
();
System.out.println(replacement.getMessage());
}
Comparisons
| Approach | Best when | Example |
|---|---|---|
Separate catch blocks | Each exception needs different handling | Show validation feedback for one type and retry another |
| Multi-catch | Several unrelated exception types have identical handling | Log a reflection failure and return an empty result |
| Catching a common superclass | Every subclass should be handled identically | Catch IOException for several I/O failures |
Catching Exception | A top-level boundary must prevent an application crash and log unexpected failures | Application entry point or worker loop |
Multi-catch versus a superclass catch
// Multi-catch: explicit list of accepted failures
catch (IllegalAccessException | NoSuchFieldException e) {
reportMetadataFailure(e);
}
Cheat Sheet
try {
riskyOperation();
} catch (FirstException | SecondException e) {
handleFailure(e);
}
- Java multi-catch has been available since Java 7.
- Separate exception types with
|, not commas. - Declare one exception variable after the final type.
- The shared variable represents the exception that was actually thrown.
- A multi-catch variable cannot be reassigned.
- Do not list both a superclass and one of its subclasses.
- Checked exception types must be throwable by code in the
tryblock. - Use multi-catch only when the handling is the same.
- Put more specific catches before broader catches when using separate
catchclauses.
catch (IllegalArgumentException | SecurityException |
IllegalAccessException | NoSuchFieldException e) {
someCode();
}
FAQ
Can Java catch multiple exceptions in one catch block?
Yes. Since Java 7, use multi-catch syntax with | between exception types.
catch (IOException | SQLException e) {
logFailure(e);
}
Can I use commas instead of | in Java multi-catch?
No. Java uses the pipe character (|) to separate exception types.
Why can I not catch Exception | IOException together?
IOException is already a subtype of Exception. Java disallows superclass-and-subclass combinations in one multi-catch because the subclass is redundant.
Can I modify the exception variable in a multi-catch block?
No. The variable is implicitly final. You can read it, log it, and pass it to methods, but cannot assign a new value to it.
Can I catch checked and unchecked exceptions together?
Yes, as long as the checked exceptions can actually be thrown by code in the try block and no listed type is a subclass of another listed type.
Should I always replace repeated catch blocks with multi-catch?
No. Use it only when handling is genuinely identical. Keep separate blocks when recovery, logging, messages, or return values should differ.
Does a multi-catch block tell me which exception occurred?
Mini Project
Description
Build a small reflection-based field reader. It receives an object and a field name, attempts to read that field, and handles common reflection failures with one multi-catch block. Reflection is a practical context because operations can fail when a field does not exist or is inaccessible.
Goal
Create a program that reads a named field from an object and reports a clear message when reflection fails.
Requirements
- Create a
Userclass with a privatenamefield. - Write a method that accepts an object and a field name.
- Use reflection to find and read the requested field.
- Use one multi-catch block for
NoSuchFieldExceptionandIllegalAccessException. - Print the field value on success and a helpful message on failure.
Keep learning
Related questions
Add External JAR Files to an IntelliJ IDEA Java Project
Learn how to add external JAR dependencies to an IntelliJ IDEA Java project using module libraries, and when to use Maven or Gradle instead.
Avoiding Java Code in JSP with JSP 2: EL and JSTL Explained
Learn how to avoid Java scriptlets in JSP 2 using Expression Language and JSTL, with examples, best practices, and common mistakes.
Call a Method After a Delay in Android Java
Learn how to run Java code after a delay in Android using Handler.postDelayed, manage the main thread, and cancel callbacks safely.