如何让我的动态代理抛出检查异常?
我需要一个接口的透明包装器,它有时会抛出检查的异常,例如IOException
. 如果没有第 3 方 AOP 或编写我自己的代理,是否有可能?手动修改接口的所有 20 个方法也不是一个选项。
如何让我的动态代理抛出检查异常?
我需要一个接口的透明包装器,它有时会抛出检查的异常,例如IOException
. 如果没有第 3 方 AOP 或编写我自己的代理,是否有可能?手动修改接口的所有 20 个方法也不是一个选项。
正如 Konrad 上面提到的,您可能正在寻找的是这个:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
Object value = method.invoke(delegate, args);
return value;
}
catch (InvocationTargetException ex) {
throw ex.getCause();
}
}
您可以使用动态代理。只要检查的异常是接口的一部分,您就可以从调用处理程序中抛出检查的异常。否则这是非法的,并且会创建一个 UndeclaredThrowableException 来包装抛出的检查异常。
interface A{
void x() throws IOException;
}
A proxy = (A) newProxyInstance(classLoader, new Class<?>[]{A.class},
new InvocationHandler() {
@Override
public Object invoke(Object arg0, Method arg1, Object[] arg2)
throws Throwable {
throw new IOException();
}
}
);
proxy.x();
输出:
Exception in thread "main" java.io.IOException
at X$1.invoke(X.java:19)
at $Proxy0.x(Unknown Source)
at X.main(X.java:22)
对于接口 A 未声明的检查异常:
interface A{
void x();
}
Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
at $Proxy0.x(Unknown Source)
at X.main(X.java:22)
Caused by: java.io.IOException
at X$1.invoke(X.java:19)
... 2 more
如果在它所代理的接口的方法的签名中声明了异常,则动态代理可以抛出已检查的异常。来自 Sun 的动态代理参考:
如果调用方法抛出异常,代理实例上的方法调用也会抛出异常。
异常的类型必须可分配给接口方法签名中声明的任何异常类型或未检查的异常类型
java.lang.RuntimeException
或java.lang.Error
.如果调用抛出的检查异常不能分配给接口方法的 throws 子句中声明的任何异常类型,则
UndeclaredThrowableException
代理实例上的方法调用将抛出 an 。将UndeclaredThrowableException
使用调用方法引发的异常来构造。