来自 java.lang.reflect.InvocationHandler 的 API javadocs:
InvocationHandler 是代理实例的调用处理程序实现的接口。
动态代理实现接口,但使用处理程序(OriginalClass)提供方法的基本实现。
要回答您的问题:
- 只要编译器没有足够的信息来确定强制转换不能成功,编译器就会让你强制转换。java.lang.reflect.Proxy 的 javadoc 中描述了动态代理的强制转换和 instanceof 测试的运行时行为。如果与接口一起使用,强制转换和 instanceof 测试将成功,但与类一起使用则不会。
- 您不能使用动态代理访问任何属性,因为它实现了接口,它不扩展处理程序类。
- 您不能使用动态代理访问任何未在接口中声明的方法,因为它实现了接口,它不扩展处理程序类。
在动态代理的实现中(例如在 invoke(...) 方法的实现中),您可以使用反射访问处理程序的成员。
这是我用来检查答案的一些测试代码:
// package ...;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import junit.framework.Assert;
import org.junit.Test;
public class TestDynamicProxy
{
@Test
public void testCast() throws Exception {
Foo foo = (Foo) TestProxy.newInstance(new FooImpl());
foo.bar(null);
System.out.println("Class: " + foo.getClass());
System.out.println("Interfaces: " + foo.getClass().getInterfaces());
Assert.assertNotNull(foo);
Assert.assertTrue(foo instanceof Foo);
Assert.assertFalse(foo instanceof FooImpl);
}
}
interface Foo
{
Object bar(Object obj) throws Exception;
}
class FooImpl implements Foo
{
public Object bar(Object obj) throws Exception {
return null;
}
}
class TestProxy implements java.lang.reflect.InvocationHandler
{
private final Object obj;
public static Object newInstance(Object obj) {
return java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new TestProxy(obj));
}
private TestProxy(Object obj) {
this.obj = obj;
}
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
Object result;
try {
result = m.invoke(obj, args);
}
catch (InvocationTargetException e) {
throw e.getTargetException();
}
catch (Exception e) {
throw new RuntimeException("unexpected invocation exception: " + e.getMessage());
}
return result;
}
}
这篇文章有很多有用的信息和示例代码。