Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 动态代理和已检查异常_Java_Dynamic Proxy - Fatal编程技术网

Java 动态代理和已检查异常

Java 动态代理和已检查异常,java,dynamic-proxy,Java,Dynamic Proxy,如何使动态代理抛出选中的异常 我需要一个透明的接口包装器,它有时会抛出检查过的异常,比如IOException。没有第三方AOP或编写自己的代理是否可能?手动修改界面的所有20种方法也不是一个选项。您可以使用动态代理。只要选中的异常是接口的一部分,就可以从调用处理程序抛出选中的异常。否则,这是非法的,并将创建一个未声明的HrowableException来包装抛出的已检查异常 interface A{ void x() throws IOException; } A proxy = (

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


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

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

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();
对于接口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

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

如果invoke方法引发异常,那么代理实例上的方法调用也会引发异常

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

如果invoke引发的选中异常不可分配给接口方法的throws子句中声明的任何异常类型,则代理实例上的方法调用将引发
未声明的throwableException
。将使用invoke方法引发的异常构造
未声明的throwableException


正如康拉德在上文中提到的,您可能正在寻找的是:

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

来源:

谢谢。注意,Method.invoke()(通常用于
InvocationHandler.invoke()
将原始异常包装在
InvocationTargetException
中,因此需要将其展开。上面指向外部博客的链接已不存在,但也有一些关于为什么这样做是一个好主意的模糊信息
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();
    }
}