skip to content

Multi-catch

The pipe form catches several unrelated exception types in one block, with the restriction that they may not be in a subtype relationship and the variable is implicitly final. It exists to remove copy-pasted catch blocks, which is the motivation interviewers want.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

5

What is the Java multi-catch clause and how do you write one?

level: juniorimportance: must knowfreq 62%

answer

  1. | (pipe) separates types
  2. one shared body, one variable
  3. Java 7 feature
  4. removes duplicated catch blocks
  5. variable typed as common supertype

basics

~10 s

Multi-catch lets one catch block handle several exception types. You list the types separated by a vertical bar (|), like catch (IOException | SQLException e), and write a single shared body.

solid answer

~40 s

Multi-catch, added in Java 7, lets a single catch block handle more than one exception type by separating the types with the | (pipe) operator: catch (IOException | SQLException e) { ... }. It exists to remove duplicated handling code — before it, you needed a separate catch block per type even when the recovery logic was identical, or you had to catch a broad common supertype and lose specificity. The handler body runs for any of the listed types. The exception variable (e here) has, as its static type, the most specific common supertype of the listed types, so inside the block you can only call methods declared on that common type. It reads left to right and there is exactly one variable name at the end.

code

java · 6 lines
java
try {
    parseAndStore(input);
} catch (NumberFormatException | SQLException e) {
    log.error("processing failed", e);   // shared handling, no duplication
    throw new ProcessingException(e);
}

go deeper

for a junior

Can write a multi-catch clause with the | operator and explain it handles several exception types in one block.

for a middle

Knows the variable is typed as the common supertype and that it removes duplication without widening to a catch-all.

for a senior

Articulates the design trade-off vs. catching a broad supertype, and the readability/precision benefit; mentions it pairs with try-with-resources from Java 7.

for a principal

Frames multi-catch within an exception-handling strategy: when to consolidate handlers, how it interacts with effectively-final analysis and exception transparency in generic/rethrow code.

## What an exception and a catch block are In Java, when something goes wrong at runtime (a file is missing, a number can't be parsed, a database call fails), the code *throws* an **exception** — an object describing the error. To deal with it you wrap risky code in a `try` block and follow it with one or more `catch` blocks. Each `catch` names an exception **type**; if the thrown object is an instance of that type, that block runs. ```java try { risky(); } catch (IOException e) { // handle I/O failures } ``` ## The problem multi-catch solves Before Java 7, each `catch` could name only **one** type. If two different exceptions needed the *same* handling, you had to repeat the body: ```java try { risky(); } catch (IOException e) { log.error("failed", e); throw new ServiceException(e); } catch (SQLException e) { log.error("failed", e); // duplicated throw new ServiceException(e); // duplicated } ``` The only alternatives were ugly: catch a broad common supertype like `Exception` (which also swallows unrelated errors you didn't mean to handle), or factor the body into a private method (extra noise). Both hurt readability. ## The multi-catch syntax Java 7 added the **multi-catch** clause. You list several types in one `catch`, separated by the `|` (vertical bar / pipe) operator, and give a single body: ```java try { risky(); } catch (IOException | SQLException e) { log.error("failed", e); throw new ServiceException(e); } ``` Rules of the syntax: - The types are separated by `|`, not commas. - There is exactly **one** variable name, written **once**, after the last type (`e` above). - The block runs if the thrown exception is an instance of **any** of the listed types. - You can list two, three, or more types. ## Type of the exception variable Inside the block, the static (compile-time) type of the variable is the **most specific common supertype** of all the listed types. For `IOException | SQLException`, both extend `Exception`, so `e` is typed as `Exception`, and you may only call methods that `Exception` declares (such as `getMessage()`). You cannot call a method that exists only on `SQLException`, because the compiler can't prove the caught object is a `SQLException`. ## Why it matters Multi-catch is purely about **eliminating duplicated handling code** while keeping handling **precise** — you name exactly the types you mean, instead of widening to a catch-all. It is a compile-time/syntax feature; it changes nothing about how exceptions are thrown or propagated.

  • What is the static type of the exception variable in catch (IOException | SQLException e)?
    Exception — the most specific common supertype of the two listed types, so only members of Exception are callable on it.
  • In which Java version was multi-catch introduced?
    Java 7 (2011), as part of Project Coin alongside try-with-resources.

saying these in an interview costs you the question

  • Saying you separate the types with commas instead of |
  • Thinking you write the variable name after each type
  • Believing multi-catch lets you call subtype-specific methods on the variable
  • Confusing it with chaining multiple separate catch blocks

context

open as a page

Why can't the exception types listed in a multi-catch clause be in a subtype/supertype relationship with each other?

level: middleimportance: should knowfreq 48%

basics

~10 s

Because one type would already cover the other. Listing both is redundant — the subtype is always also the supertype — so the compiler rejects it as a compile error to prevent meaningless code.

open as a page

When would you choose a multi-catch clause over simply catching a common supertype, and what's the trade-off?

level: middleimportance: should knowfreq 40%

basics

~20 s

Use multi-catch when only some specific exceptions share the same handling and you don't want to accidentally catch others. Catching a broad supertype like Exception is shorter but can swallow unrelated errors you should let propagate.

open as a page

Why is the exception variable in a multi-catch block implicitly final, and what practical effect does that have?

level: seniorimportance: should knowfreq 34%

basics

~20 s

The exception variable in a multi-catch block is treated as final, so you cannot reassign it inside the block. You can still call its methods and use it normally — you just can't point it at a different object.

open as a page

How does the exception variable's type in a multi-catch interact with the methods you can call and with precise rethrow analysis?

level: principalimportance: nice to knowfreq 22%

basics

~20 s

In multi-catch the variable is typed as the common parent of the listed types, so you can only call methods that parent declares. Java's 'precise rethrow' still tracks the real types, so rethrowing the variable can satisfy narrower throws clauses.

open as a page