如何覆盖Java中的方法

如何覆盖Java中的方法

本文介绍了通过反射创建对象时,如何覆盖Java中的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In Java, is it possible to override methods in a class that you create using reflection? For example, say I have the following class:

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方法,如下所示:

And in one class I want to create it directly and override its setBar method as follows:

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

是否有一种方法可以使用反射以相同的方式覆盖方法?也许是这样的吗? :

Is there a way to override a method in this same manner using reflection? Maybe something like this? :

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方法中以更改绑定值的方法.

If not, are there other ways of doing this, or an external library that could help? I am looking for way to add listeners to a setter method in order to change binded values.

推荐答案

否,以您的示例方式是不可能的.

No, it's not possible in the way of your example.

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

In your example, the Java compiler will create two separate classes:

MyObject.class
MyObject$1.class

后者是具有覆盖方法的那个.在这种情况下,它是一个匿名内部类(请参见 Java教程文档)

The latter being the one with the overridden method. In this case, it's an anonymous inner class (See Java tutorial documentation)

但是有更复杂的解决方案,涉及字节码编织库.诸如cglib,asm,javassist之类的库为您提供了一种在运行时动态创建新类并加载它们的工具.

But there is more complex solution involving bytecode weaving libraries. Libraries such as cglib, asm, javassist etc. give you a facility to dynamically create new classes at runtime and load them.

Javassist上有一个教程,介绍如何向其中添加方法运行时的类.应该有可能对其进行修改以添加/覆盖该方法,如下所示:

Javassist has a tutorial on how to add methods to classes at runtime. It should be possible to adapt it to add/override the method, something like this:

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();

这篇关于通过反射创建对象时,如何覆盖Java中的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 14:15