代码之家  ›  专栏  ›  技术社区  ›  Konrad Garus

动态代理和检查的异常

  •  9
  • Konrad Garus  · 技术社区  · 14 年前

    如何使动态代理抛出选中的异常?

    IOException . 如果没有第三方AOP或我自己写的代理,这是可能的吗?手工修改接口的所有20个方法也不是一个选择。

    3 回复  |  直到 14 年前
        1
  •  11
  •   Thomas Jung    14 年前

    可以使用动态代理。只要选中的异常是接口的一部分,就可以从调用处理程序抛出选中的异常。否则这是非法的,并将创建一个未声明的throwableexception来包装抛出的checked异常。

    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
    
        2
  •  19
  •   Magnus Reftel    5 年前

    正如康拉德在上面提到的,你可能正在寻找的是:

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

    https://web.archive.org/web/20120130204437/http://benpryor.com/blog/2006/08/15/java-dynamic-proxies-and-invocationtargetexception/

        3
  •  2
  •   Community CDub    4 年前

    如果在代理的接口的方法的签名中声明了异常,则动态代理可以抛出选中的异常。从太阳的 Dynamic Proxy reference :

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

    如果invoke抛出了一个选中的异常,该异常不可分配给接口方法的throws子句中声明的任何异常类型,那么 UndeclaredThrowableException 将由代理实例上的方法调用引发。这个 未声明的ThrowableException 将与invoke方法引发的异常一起构造。