How to not repeat code within catch blocks?
If all your finally
clauses are used to close Stream
s and such (anything that implements AutoCloseable
), you can use try-with-resources
(as suggested in one of the comments) to get rid of the finally
clause.
However, if you need a more generic solution, and have the same type of Exception
s caught and the same sort of handling in the finally
clause, you can create an abstract class such as:
abstract class SensitiveBlockHandler {
public void handle() {
try {
doHandling();
} catch (SomeException | AnotherException e) {
// TODO: handle exceptions here ...
} finally {
// TODO: cleanup here ...
}
}
protected abstract void doHandling();
}
Then, you can create inner classes to handle the different situations, either as anonymous classes or not. The code should look something like:
public SomeEntity doSomething (String someAttribute, String anotherAttribute) {
new SensitiveBlockHandler() {
protected void doHandling() {
/*
* ... independent logic ...
*/
}
}.handle();
return something;
}
Create an interface:
public interface EntityManagerAction {
public void execute(EntityManager em);
}
And a utility class:
public class EntityUtil {
public static void executeWithEntityManager(EntityManagerAction action) {
EntityManager em = someHowCreateEntityManager();
EntityTransaction tx = null;
try {
action.execute(em);
tx = em.getTransaction();
} catch (RuntimeException e) {
if (tx != null && tx.isActive()) {
tx.rollback();
}
throw e;
} finally {
em.close();
}
}
}
Now you can re-use the boiler-plate in the EntityUtil class, and your code becomes:
public SomeEntity doSomething (String someAttribute, String anotherAttribute) {
Something something;
EntityUtil.executeWithEntityManager(new EntityManagerAction() {
public void execute(EntityManager em ) {
/*
* ... independent logic ...
*/
//use the passed in 'em' here.
}
});
return something;
}
See also What is the "Execute Around" idiom?