4

I have this class that wraps an object:

public class MyWrapper implements MyInterface { private MyInterface wrappedObj; public MyWrapper(MyInterface obj) { this.wrappedObj = obj; } @Override public String ping(String s) { return wrappedObj.ping(s); } @Override public String doSomething(int i, String s) { return wrappedObj.doSomething(i, s); } // many more methods ... } 

Now I want to add complex exception handling around the wrappedObj call.

It is the same for all the methods.

How do I avoid repeating the same exception handling code over and over?

5
  • I think we'd need to see what "complex" entails. Normally I just put the duplicated parts in a common method and call where needed. Commented May 17, 2017 at 17:13
  • C# equivalent How to use try catch nicely in multiple methods? Commented May 17, 2017 at 17:15
  • Define private void handle(MyException exception) and call it from each catch block? Commented May 17, 2017 at 17:17
  • Use lambdas? i.e. Object doWithExceptionHandling(Callable callable) Commented May 17, 2017 at 17:19
  • A related C++ question: stackoverflow.com/questions/10140383/… Commented Sep 16, 2019 at 15:56

2 Answers 2

0

If your exception handling is fully generic you could implement the wrapper as InvocationHandler:

public class ExceptionHandler implements java.lang.reflect.InvocationHandler { public ExceptionHandler(Object impl) { impl_ = impl; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { return method.invoke(impl_, args); } catch (Exception e) { // do exception handling magic and return something useful return ...; } } private Object impl_; } 

and then wrap it around an instance as follows:

MyInterface instance = ... MyInterface wrapper = (MyInterface)java.lang.reflect.Proxy.newProxyInstance( instance.getClass().getClassLoader(), new Class[] { MyInterface.class }, new ExceptionHandler(instance)); wrapper.ping("hello"); 
Sign up to request clarification or add additional context in comments.

Comments

0

If you want to avoid the cost of reflection, than just use a router function.

@Override public String ping(String s) { return (String) call("ping"); } private Object call(String func) { try { switch(func) { case "ping": return wrappedObj.ping(s); // ... rest of functions ... // } } catch(Exception e) { log(e); } } 

The compiler can than effectively just jump to the function without pulling up Object specs or handlers. (A smart enough compiler may even just compile this to identical execution code as your current code, especially if you can cut the cast by always returning the same kind of object)

If you don't care about the thread and just want a default exception handler...

For the whole Java Runtime, call Thread.setDefaultUncaughtExceptionHandler
For a ThreadGroup, override ThreadGroup.uncaughtException
For a single Thread, call Thread.setUncaughtExceptionHandler

The advantage to a default handler, is that you can then add specific error handlers where needed, but the down side is you do lose the executing thread on error.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.