2010-09-15 57 views
9

如何使我的动态代理抛出检查异常?动态代理和检查异常

我需要一个接口的透明包装,有时会抛出检查异常,如IOException。没有第三方AOP或写我自己的代理服务器可能吗?手动修改接口的所有20种方法也不是一种选择。

回答

10

您可以使用动态代理。只要检查的异常是接口的一部分,就可以从调用处理程序中抛出检查的异常。否则,这是非法的,并会创建一个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) 

随着接口甲未声明的检查的异常:

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 
+10

感谢。有一点需要注意,Method.invoke()(通常在InvocationHandler.invoke()中使用)将原始异常封装在InvocationTargetException中,因此需要解包 – 2010-09-15 06:58:09

1

动态代理可以抛出检查异常,如果异常在该方法的签名中声明它正在代理的接口。来自太阳的Dynamic Proxy reference

如果异常是由invoke方法抛出,这将也由方法调用代理实例抛出。

该异常的类型必须可以分配给在接口方法的签名中声明的任何异常类型或未检查的异常类型java.lang.RuntimeExceptionjava.lang.Error

如果通过invoke引发了一个检查的异常,该异常不能分配给interface方法的throws子句中声明的任何异常类型,那么方法调用将在代理实例上抛出UndeclaredThrowableExceptionUndeclaredThrowableException将构造为invoke方法抛出的异常。

17

什么你可能正在寻找的是这一点,因为康拉德上面提到:

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(); 
    } 
} 

来源:http://benpryor.com/blog/2006/08/15/java-dynamic-proxies-and-invocationtargetexception/

+0

上面的外部博客链接已经消失,但是例如https: //amitstechblog.wordpress.com/2011/07/24/java-proxies-and-undeclaredthrowableexception/也有一些关于为什么这是一个好主意这样做blurb – vorburger 2017-03-16 15:45:52