De los javadocs API para java.lang.reflect.InvocationHandler:
InvocationHandler es la interfaz implementada por el controlador de la invocación de una instancia de proxy.
El proxy dinámico implementa la interfaz, pero utiliza el controlador (OriginalClass) para proporcionar las implementaciones básicas de los métodos.
para responder a sus preguntas:
- El compilador le permitirá lanzas con tal de que no tiene suficiente información para estar seguro de que el reparto no puede tener éxito. El comportamiento en el tiempo de ejecución de las pruebas de conversión y de instancia para proxies dinámicos se describe en javadoc para java.lang.reflect.Proxy. Las pruebas de instancia e instancia tendrán éxito si se usan con interfaces, pero no si se usan con clases.
- No puede acceder a ningún atributo utilizando el proxy dinámico porque implementa la interfaz, no extiende la clase de controlador.
- No puede acceder a ningún método no declarado en la interfaz utilizando el proxy dinámico porque implementa la interfaz, no extiende la clase de controlador.
Dentro de la implementación del proxy dinámico (por ejemplo, en la implementación de la invocación (...) método) puede acceder a los miembros del controlador utilizando la reflexión.
Aquí hay algo de código de prueba que he utilizado para comprobar mi respuesta:
// 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;
}
}
Este article tiene una gran cantidad de información útil y código de ejemplo.
¿Está seguro de que el envío de su proxy a OriginalClass funciona? Según tengo entendido, si creó el proxy para OriginalInterface, no podrá realizar el envío a OriginalClass –