我有这个包装对象的类:
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 ...
}
现在我想在wrappedObj调用周围添加复杂的异常处理。
所有方法都是一样的。
如何避免反复重复相同的异常处理代码?
答案 0 :(得分:0)
如果您的异常处理完全通用,您可以将包装器实现为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_;
}
然后将其包装在一个实例中,如下所示:
MyInterface instance = ...
MyInterface wrapper = (MyInterface)java.lang.reflect.Proxy.newProxyInstance(
instance.getClass().getClassLoader(),
new Class[] { MyInterface.class },
new ExceptionHandler(instance));
wrapper.ping("hello");
答案 1 :(得分:0)
如果你想避免反射的代价,而不仅仅是使用路由器功能。
@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);
}
}
编译器可以有效地跳转到函数而不需要提取Object规范或处理程序。 (一个足够聪明的编译器甚至可以将它编译为与当前代码相同的执行代码,特别是如果你可以通过总是返回相同类型的对象来剪切强制转换)
如果你不关心线程,只想要一个默认的异常处理程序......
对于整个Java Runtime,请致电Thread.setDefaultUncaughtExceptionHandler
对于ThreadGroup,覆盖ThreadGroup.uncaughtException
对于单个线程,请致电Thread.setUncaughtExceptionHandler
默认处理程序的优点是,您可以根据需要添加特定的错误处理程序,但不好的方法是在错误时丢失执行的线程。