從java.lang.reflect.InvocationHandler的API的javadoc:
的InvocationHandler是代理實例的調用處理程序實現的接口。
動態代理實現接口,但使用處理程序(OriginalClass)提供方法的基本實現。
回答您的問題:
- 編譯器將讓你投,只要它沒有足夠的信息可以肯定,中投也不能成功。在javadoc中爲java.lang.reflect.Proxy描述了動態代理的cast和instanceof測試的運行時行爲。如果與接口一起使用,Casts和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;
}
}
這article有很多有用的信息和示例代碼。
你是否確實將你的代理強制轉換爲OriginalClass?在我的理解中,如果你爲OriginalInterface創建了代理,那麼你不應該能夠轉換成OriginalClass – 2010-05-03 10:26:15