Multiple Catch Blocks and Multi-Catch
One piece of code can fail in more than one way. Reading a quantity from text can fail because the text isn't a number; dividing by it can fail because it's zero. Each problem deserves its own response. A try can have several catch blocks, one per exception type, and Java runs the first one that matches. When several types need the same response, a multi-catch handles them in one block.
One Catch per Problem
public class PerPerson {
static void split(String bill, String people) {
try {
int total = Integer.parseInt(bill);
int n = Integer.parseInt(people);
System.out.println("Each pays Rs. " + total / n);
} catch (NumberFormatException e) {
System.out.println("Please type numbers only: " + e.getMessage());
} catch (ArithmeticException e) {
System.out.println("Can't split among zero people");
} catch (RuntimeException e) {
System.out.println("Something else went wrong: " + e);
}
}
public static void main(String[] args) {
split("1200", "4");
split("1200", "four");
split("1200", "0");
}
}Each pays Rs. 300
Please type numbers only: For input string: "four"
Can't split among zero peopleHow it works
- Java checks the catch blocks from top to bottom and runs the first whose type matches the thrown exception (or is a parent of it).
"four"throwsNumberFormatException: the first catch runs, and the others are skipped."0"throwsArithmeticException: the first catch doesn't match, the second does.- The last block,
RuntimeException, is a safety net for anything else unchecked.
Why Specific Must Come First
If a general type came first, it would catch everything, and the specific block below could never run. Java treats that as a mistake and refuses to compile:
public class Order {
public static void main(String[] args) {
try {
Integer.parseInt("x");
} catch (Exception e) {
System.out.println("general");
} catch (NumberFormatException e) {
System.out.println("specific");
}
}
}Order.java:7: error: exception NumberFormatException has already been caught
} catch (NumberFormatException e) {
^
1 errorMulti-Catch: One Handler for Several Types
When different exceptions need the same handling, list them with | in one catch (Java 7 and later):
public class MultiCatch {
static int perPerson(String bill, String people) {
try {
return Integer.parseInt(bill) / Integer.parseInt(people);
} catch (NumberFormatException | ArithmeticException e) {
System.out.println("Bad input (" + e.getClass().getSimpleName()
+ "), using 0");
return 0;
}
}
public static void main(String[] args) {
System.out.println(perPerson("900", "3"));
System.out.println(perPerson("900", "x"));
System.out.println(perPerson("900", "0"));
}
}300
Bad input (NumberFormatException), using 0
0
Bad input (ArithmeticException), using 0
0How it works
catch (NumberFormatException | ArithmeticException e) catches either type. Inside, e really is whichever one was thrown, as getSimpleName() shows.
Two rules apply to multi-catch:
Multi.java:5: error: Alternatives in a multi-catch statement cannot be related by subclassing
} catch (NumberFormatException | IllegalArgumentException e) {
^
Alternative NumberFormatException is a subclass of alternative IllegalArgumentException
MultiFinal.java:6: error: multi-catch parameter e may not be assigned
e = new ArithmeticException();
^- The types can't be parent and child:
NumberFormatExceptionalready is anIllegalArgumentException, so listing both is pointless. - The variable
eis implicitlyfinal; you can't assign a new exception to it.
Common Mistakes
General catch blocks first. It's a compile error; order from specific to general.
Catching Exception as the only block. You lose the chance to respond differently to different problems, and you also catch bugs.
Listing a parent and child in one multi-catch. Keep only the parent, or only the specific types you mean.
Interview Corner
Can we have multiple catch blocks for one try?
Yes. Each catch handles one exception type, and they're checked in order; only the first matching block runs. More specific subclasses must appear before their superclasses, otherwise the compiler reports that the exception "has already been caught".
What is multi-catch?
Since Java 7, a single catch block can handle several unrelated exception types separated by |, as in catch (IOException | SQLException e). The alternatives can't be subclasses of each other, and the catch parameter is implicitly final.
Practice
- Easy: Write a method that reads an index and a word from strings and prints the character at that index. Catch
NumberFormatExceptionandStringIndexOutOfBoundsExceptionseparately. - Harder: Rewrite your answer to use one multi-catch, printing the exception's simple class name.
Key Takeaways
Was this tutorial helpful?