首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Javassist方法和调用

Javassist方法和调用
EN

Stack Overflow用户
提问于 2012-12-10 17:13:21
回答 2查看 12.8K关注 0票数 7

我坚持使用javassist.我在运行时向我的对象类添加了一个新方法。

我的object类:

代码语言:javascript
复制
package tmp3;

public class Car {
    public Car(){}
}

我的测试类:

代码语言:javascript
复制
package tmp3;

import java.lang.reflect.Method;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;

public class TestMain {
    public static void main(String[] args) {
        try {

            CtClass ctclass = ClassPool.getDefault().get("tmp3.Car");
            CtMethod newmethod = CtNewMethod.make("public void testPrint() { System.out.println(\"test ok\"); }",ctclass);
            ctclass.addMethod(newmethod);
            ctclass.writeFile();

            for(Method me: ctclass.toClass().getDeclaredMethods()){ //test print, ok
                System.out.println(me.getName());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

但在那之后,我不知道如何调用它。我读到过javassist没有调用方法的能力。那么,我如何才能调用我刚才用javassist添加的方法呢?

我在两天内尝试了很多东西,但都没有成功。你能帮我弄一下这个吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-10 17:51:56

Java类具有静态接口,这意味着,正如您可能已经知道的那样,默认情况下,Java不是为在运行时向类添加方法而设计的,所以它有点棘手,但实现您想要的并不难。

您已经使用了Javassist (一个字节码修改器框架)来设计您的已编译类,以添加更多表示新方法的字节码。您可以选择以下两种场景之一:

场景1:在注入之前与您的汽车类一起编译的代码

在这种情况下,当您的代码正在编译时,Java Compiler只知道Car接口,而没有任何注入。所以你不能直接调用注入的方法,就像这样:

代码语言:javascript
复制
 Car car = new Car();
 car.testPrint();

你必须像@Scorpion正确评论的那样,通过反射来做到这一点:

代码语言:javascript
复制
 Car car = new Car();
 Method method = car.getClass().getMethod("testPrint", new Class[]{});
 method.invoke(car,new Object[]{});

但这并不是唯一的方法。

场景2:使用编译和注入的类的代码

如果编译Car类,注入它,然后对编译的类进行编写代码(例如,将Car类放在jar文件中),您将能够像调用任何其他常规方法一样调用注入的方法。

执行以下练习:

  1. 编译您的Car
  2. 运行您的TestMain,它将在您的集成开发环境中执行另一个项目,并将包含注入类的目录添加到该项目的类路径中创建一个仅包含注入类的jar,并将该jar添加到jar创建新Car实例的新项目中的一个类,请注意,您现在可以轻松地调用testPrint方法了。

<代码>G222

有几件事你应该注意:

  • 如果你用注入的类覆盖你的原始类,你可能会得到一个无效的类,这会导致一个java.lang.ClassFormatError,并显示一条错误消息,告诉你有一个截断的类文件。如果Javassist没有将所有的字节码加载到内存中,并试图对同一个类文件进行读写操作,就会发生这种情况,这会导致整个系统的混乱。要避免这种情况,您可以在写入文件之前写入其他路径或确保已将所有字节码加载到内存中(使用CtClass中的toByteCode() )。
  • 如果您有两个类文件,一个包含注入代码,另一个包含原始代码,请记住在您的文件中只有一个
票数 9
EN

Stack Overflow用户

发布于 2015-08-11 05:53:08

使用java反射来调用它,javassist用于类的修改和加载……然后使用java反射来运行它(调用...)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13797919

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档