Java 代理和未声明的HrowableException
我想问的是,为什么当代码运行指令instance.run(new IOException())时,它会抛出未声明的hrowableexception 根据oracle的文档,在InvocationHandler的invoke方法中,如果此方法引发了一个选中的异常,该异常不可分配给接口方法的throws子句中声明的任何异常类型,然后,代理实例上的方法调用将引发包含此方法引发的异常的未声明的HrowableException 在这种情况下,IOException与IOException相似,那么为什么它会抛出未声明的HrowableException而不是IOException?因为当您从具有相似方法签名的两个接口创建代理时,这些方法签名将合并为满足两个接口要求的一个签名 由于Java 代理和未声明的HrowableException,java,Java,我想问的是,为什么当代码运行指令instance.run(new IOException())时,它会抛出未声明的hrowableexception 根据oracle的文档,在InvocationHandler的invoke方法中,如果此方法引发了一个选中的异常,该异常不可分配给接口方法的throws子句中声明的任何异常类型,然后,代理实例上的方法调用将引发包含此方法引发的异常的未声明的HrowableException 在这种情况下,IOException与IOException相似,那么为什
eofeexception
继承自IOException
方法签名将
import java.io.EOFException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public class ProxyDemo {
private final ClassLoader loader = getClass().getClassLoader();
private final InvocationHandler throwHandler = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
throw (Throwable) args[0];
}
};
public interface ThrowsIOException {
Object run(Throwable toThrow) throws IOException;
}
public interface ThrowsEOFException {
Object run(Throwable toThrow) throws EOFException;
}
public void testDeclaredExceptionIntersectionIsSubtype() throws Exception {
ThrowsIOException instance = (ThrowsIOException) Proxy.newProxyInstance(loader,
new Class[] {ThrowsIOException.class, ThrowsEOFException.class}, throwHandler);
try {
instance.run(new EOFException());
} catch (EOFException expected) {
}
try {
instance.run(new IOException());
} catch (UndeclaredThrowableException expected) {
}
try {
instance.run(new Exception());
} catch (UndeclaredThrowableException expected) {
}
}
public static void main(String[] args) throws Throwable {
ProxyDemo cl = new ProxyDemo();
cl.testDeclaredExceptionIntersectionIsSubtype();
}
}
您可以通过创建虚拟类来测试这一点:
public Object run(Throwable toThrow) throws EOFException
这是因为您可以缩小抛出的异常范围(使用抛出EOFEException
覆盖抛出IOException
很好),但不能扩大它(使用抛出IOException
覆盖抛出EOFEException
是非法的)
因此,当您调用该方法并抛出
EOFEException
时,它符合代理生成的方法签名(声明了该签名),并且一切正常。但是,当您抛出IOException
时,它与签名不符(未声明),并且您得到未声明的HrowableException
,谢谢,但是如果两个接口无法合并,会发生什么情况呢?newProxyInstance
将抛出IllegalArgumentException
我在oracle文档中找到了答案,关于“方法在多个代理接口中重复”,但仍然感谢您的帮助。
public class Test implements ThrowsIOException, ThrowsEOFException {
@Override
public Object run(Throwable toThrow) throws IOException // compiler error
{
return null;
}
}
public class Test implements ThrowsIOException, ThrowsEOFException {
@Override
public Object run(Throwable toThrow) throws EOFException // valid
{
return null;
}
}