如何覆盖使用ClassLoader实例化的类的方法

时间:2012-01-22 13:55:12

标签: java reflection

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

Foo bar = new Foo(){

    public void fighters(){
          //some stuff
    }

};

问题是:类的名称存储在String中。 我明显的举措是使用Constructor.newInstance(Object o)方法创建一个新实例,如下所示:

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

虽然这段代码成功创建了一个新的类实例,但我现在还不知道如何覆盖它的方法。

有什么建议吗?

1 个答案:

答案 0 :(得分:2)

我认为你有几个选择,其中没有一个很好,并且所有人都在讨论一个建筑问题的天堂,以及你如何解决你所面临的问题。

委派包装

创建一个如下所示的 DelegaingFoo 类:

class DelegatingFoo {

    Callable callMe;

    public DelegatingFoo(Callable callMe) {
        this.callMe = callMe;
    }

    public void fighters(){
          calLMe.call();
    }

};

替代实例化,将Callable对象传递给构造函数,如上所示。这会从你注入它的位中解除你想要运行的代码。

使用JVM语言

编译为可以通过 javax.script 运行的东西,例如BeanShell,Groovy等。根据你最终做的事情,这可能是一个可行的选择。

自定义类加载器

如果你可以选择使用另一个类加载器(它提出了它自己的问题),这可能会充满它自己的问题,并创建一些非常复杂的东西。如果您决定认真考虑这个问题,那么查看OSGi类加载框架之类的内容可能会给您一些线索(甚至可能在一定程度上适合)。

字节码操作

有一些库可以帮助实现字节码重组/拦截/生成/更改:

警告

应该注意的是,以上所有都是黑客攻击,随着你的堕落而越来越堕落。我会尽快让我的架构同行审查,因为我会把钱放在那里有一个更清洁的&更清楚地了解你正在做的事情。

请记住,您编写的代码应该更容易阅读 - 否则您会为自己(或未来的项目所有者)造成维护问题。