2011-11-24 18 views
5

¿Es posible anular de forma reflexiva un método para una instancia determinada de una clase?anula un método para una instancia de una clase?

Precondición: el juego tiene un método anulable act().

public class Foo { 

    public Method[] getMethods() { 
    Class s = Game.class; 
    return s.getMethods(); 
    } 

    public void override() 
    { 
    Method[] arr = getMethods() 
    for (int i = 0; i<arr.length; i++) 
    { 
     if (arr[i].toGenericString().contains("act()") 
     { 
     // code to override method (it can just disable to method for all i care) 
     } 
    } 
    }     
} 
+1

Es posible hacer algo como esto usando ingeniería de byte y proxies, a menos que realmente necesite este tipo de magia negra, solo use composición y delegación. –

+2

¿Por qué no es suficiente usar un método de clase interna anónima local? Subclasificación de la clase real. – zeller

+0

¿sería más fácil crear dinámicamente una subclase a partir de una instancia determinada, anular el método act en esa clase y deshacerse de la instancia anterior? –

Respuesta

7

Si juego es una interfaz o implementa una interfaz con el método act() puede utilizar Proxy para eso. Si la interfaz es pequeña, la forma más elegante probablemente sea crear una clase que lo implemente utilizando el Decorator design pattern.

+2

+1 para la sugerencia del decorador. No hay necesidad de reflexionar aquí. – artbristol

+2

El juego es una clase –

+0

¿Ejemplos de código? –

1

No es posible anular dinámicamente los métodos de una clase utilizando Java puro. The third-party library cglib puede crear subclases dinámicas. Es posible que desee verificarlo.

Si puede codificar contra la interfaz, puede usar Java dynamic proxy para crear un objeto proxy que anule el comportamiento, como en el ejemplo siguiente. Supongamos que Game estaba implementando una interfaz IGame.

class GameInvocationHandler implements InvocationHandler 
{ 
    private Game game; 
    public GameInvocationHandler(Game game) 
    { 
     this.game = game; 
    } 
    Object invoke(Object proxy, Method method, Object[] args) 
    { 
     if (method.toGenericString().contains("act()") 
     { 
      //do nothing; 
      return null; 
     } 
     else 
     { 
      return method.invoke(game, args); 
     } 
    } 
} 

Class proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), IGame.class); 
IGame f = (IGame) proxyClass.getConstructor(InvocationHandler.class).newInstance(new Object[] { }); 
Cuestiones relacionadas