Чтобы сделать это, вам понадобится некоторая AOP-инфраструктура, которая будет использовать прокси вокруг вашего метода. Этот прокси перехватит исключение и выполнит блок finally. Честно говоря, если вы еще не используете фреймворк, поддерживающий AOP, я не уверен, что использовал бы его только для сохранения этих нескольких строк кода.
Вы можете использовать следующий шаблон, чтобы сделать это более элегантным способом:
public void doSomething() {
logAndCleanup(new Callable<Void>() {
public Void call() throws Exception {
implementationOfDoSomething();
return null;
}
});
}
private void logAndCleanup(Callable<Void> callable) {
try {
callable.call();
}
catch (Exception e) {
MyEnv.getLogger().log(e);
}
finally {
genericCleanUpMethod();
}
}
Я просто использовал Callable<Void>
в качестве интерфейса, но вы можете определить свой собственный Command
интерфейс:
public interface Command {
public void execute() throws Exception;
}
и, таким образом, избегайте необходимости использовать универсальный Callable<Void>
и возвращать null из Callable.
РЕДАКТИРОВАТЬ: если вы хотите вернуть что-то из ваших методов, то сделайте метод logAndCleanup()
универсальным. Вот полный пример:
public class ExceptionHandling {
public String doSomething(final boolean throwException) {
return logAndCleanup(new Callable<String>() {
public String call() throws Exception {
if (throwException) {
throw new Exception("you asked for it");
}
return "hello";
}
});
}
public Integer doSomethingElse() {
return logAndCleanup(new Callable<Integer>() {
public Integer call() throws Exception {
return 42;
}
});
}
private <T> T logAndCleanup(Callable<T> callable) {
try {
return callable.call();
}
catch (Exception e) {
System.out.println("An exception has been thrown: " + e);
throw new RuntimeException(e); // or return null, or whatever you want
}
finally {
System.out.println("doing some cleanup...");
}
}
public static void main(String[] args) {
ExceptionHandling eh = new ExceptionHandling();
System.out.println(eh.doSomething(false));
System.out.println(eh.doSomethingElse());
System.out.println(eh.doSomething(true));
}
}
РЕДАКТИРОВАТЬ: И с Java 8, упакованный код может быть немного красивее:
public String doSomething(final boolean throwException) {
return logAndCleanup(() -> {
if (throwException) {
throw new Exception("you asked for it");
}
return "hello";
});
}