【问题标题】:How can I override methods in Java when I create an Object via reflection?通过反射创建对象时如何覆盖 Java 中的方法?
【发布时间】:2012-12-08 17:18:44
【问题描述】:

Java 中,是否可以覆盖您使用reflection 创建的类中的方法?例如,假设我有以下课程:

public class MyObject
{
    public String foo, bar;

    public MyObject(String foo)
    {
        this.foo = foo;
        this.bar = foo + "bar";
    }

    public void setBar(String bar)
    {
        this.bar = bar;
    }
}

在一个类中,我想直接创建它并覆盖其setBar 方法,如下所示:

MyObject obj = new MyObject("something")
{
    @Override
    public void setBar(String bar)
    {
        this.bar = this.foo;
    }
};

有没有办法使用反射以同样的方式覆盖方法?也许是这样的? :

Class<?> _class = Class.forName("com.example.MyObject");
Constructor<?> _constructor = _class.getConstructor(new Class<?>[]{String.class});
Method m = _class.getMethod("setBar", new Class<?>[]{String.class});
Object obj = _constructor.newInstance("Foo String")
{
    m = new Method(new Class<?>[]{String.class})
    {
        System.out.println("Foobar");
    }
};

如果没有,是否有其他方法可以做到这一点,或者外部库可以提供帮助?我正在寻找将侦听器添加到 setter 方法以更改绑定值的方法。

【问题讨论】:

  • 你需要一个动态代码生成库,比如javassist

标签: java reflection overriding


【解决方案1】:

不,按照你的例子是不可能的。

在您的示例中,Java 编译器将创建两个单独的类:

MyObject.class
MyObject$1.class

后者是具有覆盖方法的那个。在这种情况下,它是一个匿名内部类(参见Java tutorial documentation

但还有更复杂的解决方案涉及字节码编织库。 cglib、asm、javassist 等库为您提供了在运行时动态创建新类并加载它们的便利。

Javassist 有一个关于如何add methods to classes at runtime 的教程。应该可以对其进行调整以添加/覆盖该方法,如下所示:

CtClass origClazz = ClassPool.getDefault().get("org.example.MyObject");
CtClass subClass = ClassPool.getDefault().makeClass(cls.getName() + "New", origClazz);
CtMethod m = CtNewMethod.make(
             "public void setBar(String bar) { this.bar = bar; }",
             subClass );
subClass .addMethod(m);
Class clazz = cc.toClass();

【讨论】:

  • 这几乎正是我想要的——但我绝对能适应它。谢谢!
  • 有人尝试用 Mock 做这个吗?
【解决方案2】:

如果您要返回接口类型的对象,您可以使用Proxy.newProxyInstance 来获取接口的实例,该实例将动态发送方法调用到InvocationHandler 对象,您可以编写该对象来执行您想要的任何自定义行为.

【讨论】:

    【解决方案3】:

    不,您要求的是运行时编译之类的东西。虽然并非不可能,但它肯定不是反射 API 提供的。

    【讨论】:

      猜你喜欢
      • 2010-10-19
      • 2013-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      • 2011-02-24
      相关资源
      最近更新 更多