如何重写用ClassLoader实例化的类的方法



我想创建一个类的对象,并覆盖它的一些方法。例如:

Foo bar = new Foo(){
    public void fighters(){
          //some stuff
    }
};

问题是:类的名称存储在一个String中。我显而易见的做法是使用Constructor.newInstance(Objecto)方法创建一个新实例,如下所示:

Class c = cl.loadClass("com.pom.Foo");
Foo f = (Foo) (c.getDeclaredConstructor(String.class).newInstance("Hello!"));

尽管这段代码成功地创建了该类的一个新实例,但我现在不知道如何重写它的方法。

有什么建议吗?

我认为你有几个选择,没有一个是好的,而且都是关于如何解决所面临的问题的建筑问题。

委托包装

创建一个DelegangFoo类,如下所示:

class DelegatingFoo {
    Callable callMe;
    public DelegatingFoo(Callable callMe) {
        this.callMe = callMe;
    }
    public void fighters(){
          calLMe.call();
    }
};

相反,将其实例化,将一个Callable对象传递到构造函数中,如上面所述。这会使您想要运行的代码与注入它的位脱节。

使用JVM语言

编译到可以通过javax.script运行的东西,如BeanShell、Groovy等。根据您最终要做的事情,这可能是一个可行的选项。

自定义类加载器

如果您可以选择使用一个替代类加载器(它呈现自己的问题),这将充满它自己的问题,并创建一些非常复杂的东西。如果你决定认真考虑这一点,那么看看像OSGi类加载框架这样的东西可能会给你一些线索(在某种程度上,它甚至可能是合适的)。

字节码操作

有几个库可以帮助实时执行字节码挖掘/拦截/生成/更改:

  • BECL-http://commons.apache.org/bcel/
  • CGLib-http://cglib.sourceforge.net/

警告

需要注意的是,以上都是技巧,随着你往下走,堕落程度会越来越高。我会尽快得到我的建筑同行的审查,因为我会把钱花在那里做一个清洁工&对你正在做的事情采取更清晰的方法。

记住,你写的代码应该更容易阅读,否则你会给自己(或未来的项目所有者)带来维护难题。

相关内容

  • 没有找到相关文章

最新更新