# Use Multi Catch
# Description
Java 7 introduced the possibility to merge multiple catch clauses into a single multi-catch clause. Merging is only possible if the catch statements are identical.
# Benefits
Using this rule reduces clutter and improves readability.
# Tags
# Code Changes
# Merge and reduce subtype exceptions.
Pre
public int cornerCaseInheritance(int i) {
try {
throwSomething(i);
} catch (SecondChildChildException e) {
e.printStackTrace();
} catch (SecondChildException e) {
e.printStackTrace();
} catch (SecondChildSecondException e) {
e.printStackTrace();
} catch (FirstException e) {
e.printStackTrace();
} catch (SecondException e) {
e.printStackTrace();
}
return i;
}
Post
public int cornerCaseInheritance(int i) {
try {
throwSomething(i);
} catch (FirstException | SecondException e) {
e.printStackTrace();
}
return i;
}
# Merge identical catch clauses with different exception names
Pre
public int cornerCaseDifferentExceptionNames(int i) {
try {
throwSomething(i);
} catch (SecondChildChildException e) {
e.printStackTrace();
} catch (SecondChildException e2) {
e2.printStackTrace();
} catch (SecondChildSecondException e3) {
e3.printStackTrace();
} catch (FirstException e4) {
e4.printStackTrace();
} catch (SecondException e5) {
e5.printStackTrace();
}
return i;
}
Post
public int cornerCaseDifferentExceptionNames(int i) {
try {
throwSomething(i);
} catch (FirstException | SecondException e) {
e.printStackTrace();
}
return i;
}
# Merging identical catch clauses only
Pre
public int cornerCaseDifferentBodies(int i) {
try {
throwSomething(i);
} catch (FirstException e) {
log.log(Level.TRACE, e.getMessage()); // A
} catch (SecondException e) {
log.log(Level.TRACE, e.getMessage()); // A
} catch (ThirdException e) {
log.log(Level.TRACE, e); // B
} catch (FourthException e) {
log.log(Level.TRACE, e.getCause()); // C
} catch (FifthException e) {
log.log(Level.TRACE, e.getCause()); // C
} catch (SixthException e) {
log.log(Level.TRACE, e.toString()); // D
}
return i;
}
Post
public int cornerCaseDifferentBodies(int i) {
try {
throwSomething(i);
} catch (FirstException | SecondException e) {
log.log(Level.TRACE, e.getMessage()); // A
} catch (ThirdException e) {
log.log(Level.TRACE, e); // B
} catch (FourthException | FifthException e) {
log.log(Level.TRACE, e.getCause()); // C
} catch (SixthException e) {
log.log(Level.TRACE, e.toString()); // D
}
return i;
}
# Bytecode JDK 1.8
Pre
public void original() {
try {
throwSomeExceptions();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (InvalidClassException e) {
e.printStackTrace();
}
}
0 aload_0
1 invokespecial #2 <at/splendit/MultiCatchSamples.throwSomeExceptions>
4 goto 20 (+16)
7 astore_1
8 aload_1
9 invokevirtual #4 <java/io/FileNotFoundException.printStackTrace>
12 goto 20 (+8)
15 astore_1
16 aload_1
17 invokevirtual #6 <java/io/InvalidClassException.printStackTrace>
20 return
Post
public void transformed() {
try {
throwSomeExceptions();
} catch (FileNotFoundException | InvalidClassException e) {
e.printStackTrace();
}
}
0 aload_0
1 invokespecial #2 <at/splendit/MultiCatchSamples.throwSomeExceptions>
4 goto 12 (+8)
7 astore_1
8 aload_1
9 invokevirtual #7 <java/io/IOException.printStackTrace>
12 return
Use a Java Refactoring Tool
No license required
You can review this refactoring on your code without a license by installing jSparrow to your Eclipse IDE. Install the plug-in from Eclipse IDE: Eclipse Marketplace.
System-wide Refactoring
Do you want to automate this refactoring (and many more) to your system-wide code? The automatic application of this system-wide refactoring can be unlocked by acquiring your jSparrow license.