:
의 InvocationHandler는 프록시 인스턴스의 호출 핸들러가 구현하는 인터페이스입니다.
동적 프록시는 인터페이스를 구현하지만 처리기 (OriginalClass)를 사용하여 메서드의 기본 구현을 제공합니다.
귀하의 질문에 대답하려면 :
- 컴파일러는 당신이 한이 캐스트가 성공할 수 없음을 확신 할 수있는 충분한 정보를 가지고 있지 않기 때문에 캐스팅하게됩니다. 동적 프록시에 대한 형변환 및 instanceof 테스트의 런타임 동작은 java.lang.reflect.Proxy 용 javadoc에 설명되어 있습니다. 캐스트 및 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로 캐스팅하지 않아야합니다. –