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

Java 如何重写用ClassLoader实例化的类的方法,java,reflection,Java,Reflection,我想创建一个类的对象,并重写它的一些方法。例如: Foo bar = new Foo(){ public void fighters(){ //some stuff } }; 问题是:类的名称存储在字符串中。 我明显的行动是使用构造函数创建一个新实例。newInstance(Object o)方法,如下所示: Class c = cl.loadClass("com.pom.Foo"); Foo f = (Foo) (c.getDeclaredConstr

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

Foo bar = new Foo(){

    public void fighters(){
          //some stuff
    }

};
问题是:类的名称存储在字符串中。 我明显的行动是使用构造函数创建一个新实例。newInstance(Object o)方法,如下所示:

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

    Callable callMe;

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

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

};
虽然这段代码成功地创建了该类的新实例,但我现在不知道如何重写它的方法


有什么建议吗?

我想你有几个选择,没有一个是好的,而且都是关于你如何解决你遇到的问题的架构问题

授权包装器

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

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

    Callable callMe;

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

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

};
而是实例化它,像上面那样将一个可调用对象传递到构造函数中。这将使要运行的代码与注入它的位分离

使用JVM语言

编译成可以通过javax.script运行的东西,如BeanShell、Groovy等。这可能是一个可行的选择,具体取决于您最终要做什么

定制类加载器

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

有几个库可以帮助进行字节码搜索/截取/生成/动态更改:

  • BECL-
  • CGLib-
警告

应该注意的是,以上所有的都是黑客,随着你的深入,他们的堕落程度越来越高。我会让我的架构同行尽快审查,因为我会把钱花在有一个更干净、更清晰的方法来做你正在做的事情上


请记住,您编写的代码应该更易于阅读-否则您会给自己(或未来的项目所有者)带来维护方面的麻烦。

为什么您不能创建一个覆盖该方法的类,对其进行编译,然后实例化该类而不是Foo?Java是一种静态编译语言,您不能这样做。这工作用的工具不对。@skaffman:那不太正确。您可以进行运行时代码注入(例如使用BCEL之类的东西)。(不是说你应该这样做,只是你可以。)@JBNizet如果你真的非常想,你甚至可以动态地这样做。@PeterLawrey:我知道,但是如果一个简单的静态OO方法解决了这个问题,我不会这么做。如果不知道问题背后的问题,我不会建议这么难的解决办法。谢谢大家@谢谢你的详细回复。委派类的想法非常好。我仍然建议对整个体系结构进行更广泛的审查!无论如何,祝你好运。