2011-03-04 12 views
6

Ahora mismo lo siguiente:¿Se puede forzar a un objeto java a implementar una interfaz en tiempo de ejecución?

1) Una interfaz java.

2) una clase Java concreto que hace no implementar la interfaz antes mencionada, pero hace contienen una firma del método búsqueda de cada uno de los métodos definidos en la interfaz.

Como no puedo cambiar la implementación del elemento 2, me gustaría saber si es posible hacer un método que acepte una instancia del elemento 1 como argumento para aceptar el elemento 2 sin una excepción de lanzamiento de clase.

Parece que las diversas mecánicas de telar/coerción/AOP en Spring deberían hacer esto posible, pero no sé cómo hacerlo.

¿Hay alguna manera de que esto suceda?

+2

¿No puedes simplemente hacer un contenedor que implementa la interfaz y reenvía todo? – Erik

+0

+1 para el contenedor –

+0

¿Alguien sabe si hay un nombre para este patrón (lo que OP quiere) donde está 'lanzando' un objeto con la firma correspondiente en una interfaz? –

Respuesta

7

¿Se puede forzar a un objeto java a implementar una interfaz en tiempo de ejecución?

Sí, usando dynamic proxies o reescritura de código byte. Sin embargo, para mí parece que estás buscando Adapter pattern.

+0

¿Tiene enlaces a alguna documentación sobre cómo hacerlo, preferiblemente de manera declarativa? – dskiles

+0

@dskiles, utilizando proxies, consulte ['Java Dynamic Proxy - Cómo referencia la clase concreta'] (http://stackoverflow.com/questions/5167185/java-dynamic-proxy-how-reference-concrete-class/5167267#5167267) Para un enfoque de AoP, eche un vistazo a los proyectos [aspectj] (http://www.eclipse.org/aspectj/) o [cglib] (http://cglib.sourceforge.net/). –

+0

+1 - buen consejo. – Nilesh

3

No puede hacer que el objeto implemente la interfaz, pero puede usar algo como Proxy para crear un objeto que implemente la interfaz y utilice la reflexión para llamar al miembro apropiado en el objeto original.

Por supuesto, si es sólo un tipo de interfaz y el tipo de hormigón, fácilmente se podría escribir un envoltorio tales sin utilizar Proxy:

public class BarWrapper implements Foo 
{ 
    private final Bar bar; 

    public BarWrapper(Bar bar) 
    { 
     this.bar = bar; 
    } 

    public int someMethodInFoo() 
    { 
     return bar.someMethodInFoo(); 
    } 

    // etc 
} 
0

Básicamente hay dos maneras:

a) escriba un decorador alrededor de su Objeto que implemente la interfaz y delegue en su objeto (esto puede hacerse utilizando proxies o escribiendo una clase de adaptador simple)

b) cambie el código de byte. Spring AOP no es lo suficientemente potente como para hacer eso, pero sí el compilador de AspectJ. Es una sola línea:

declare parents: YourClass implements YourInterface; 

Puesto que usted no tiene acceso a la fuente de la clase tendrá que usar ya sea de carga o Weaving Tiempo tejer el frasco biblioteca. Todo esto se explica bien en AspectJ in Action por Ramnivas Laddad

1

Esto debería poder resolverse con un adaptador. tienes otro clase definida que implementa la interfaz y delega en el objeto real:

class YourAdapter implements YourInterface { 

    private final YourClass realObject; 

    public YourAdapter(YourClass realObject) { 
     this.realObject = realObject; 
    } 

    @Override 
    public methodFromInterface() { 
     // you said the class has the same method signatures although it doesn't 
     // implement the interface, so this should work fine: 
     realObject.methodFromInterface(); 
    } 

    // ....... 

} 

Ahora, dado un método que espera YourInterface y un objeto de tipo YourClass:

void someMethod(YourInterface param) {} 

void test() { 
    YourClass object = getFromSomewhere(); 
    someMethod(YourAdapter(object)); 
} 
+0

Eso es lo que tengo ahora, pero esperaba omitir el paso del adaptador, si es posible. – dskiles

+0

Luego tendrá que seguir el enfoque Proxy mencionado en algunas de las otras respuestas, si no le importa el reflejo. –

0

Probablemente puede hacer lo que quiere con Javassist, ya sea modificando el bytecode de la clase o creando una clase contenedora/proxy.

Cuestiones relacionadas