为一个类的实例重写方法?

5

是否可以反射性地重写类的给定实例的方法?

前提条件:Game有一个可重写的方法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
使用字节码工程和代理可以做到这样的事情,除非你真的需要这种黑魔法,否则请使用组合和委托。 - Maurício Linhares
2
为什么仅使用方法局部匿名内部类是不够的?需要对实际类进行子类化。 - zeller
从给定实例动态创建子类,重写该类中的act方法并且释放先前的实例会更容易吗? - Maxwell Dergosits
我以前从未做过这个,但这个问题似乎非常有用...期待它的答案.. 我会给它一个+1... - amod
2个回答

7
如果游戏是一个接口或实现了一个方法为act()的接口,您可以使用Proxy。如果接口很小,最优雅的方式可能是创建一个实现它并采用装饰器设计模式的类。

代码示例? - Jemshit Iskenderov

0

使用纯Java无法动态覆盖类的方法。第三方库cglib可以创建动态子类。您可能需要查看一下。

如果您可以编写接口代码,则可以使用Java动态代理创建代理对象,该对象覆盖行为,例如下面的示例。假设Game正在实现接口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[] {  });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接