运行时的类

时间:2009-11-04 12:00:21

标签: java reflection

有没有办法在运行时创建Java类@ (类方法n变量),使用Java反射API

7 个答案:

答案 0 :(得分:5)

你不能用反射做到这一点。您需要一个字节码操作库,如Jakarta BCEL

答案 1 :(得分:3)

标准Java API提供了一组静态方法,允许您动态创建实现一个(或多个)接口的类。 这些方法是java.lang.reflect.Proxy类的一部分。

答案 2 :(得分:3)

你需要什么?

在一个非常宽松的庄园中解释这个问题我可以想到四个可能的选择。

如果你有一个课程也添加了一些东西,你可能会发现Aspect-oriented programming就是你真正想要的。

如果您有一个想要动态实现的界面(由barjak发布),您想要的是java.lang.reflect.Proxy。这不允许在运行时创建“代码”,而是允许您将现有代码链接到接口。

最后(我知道三个)你实际上已经在运行时构建了随机类。您需要cglibBCEL之类的内容。虽然有些情况需要这样做,但IMO很少见。

另一个选择是你并不真正需要运行时而是建立时间。在这种情况下,您可以使用annotationsapt(Java 5)/ Processor(Java 6)。

答案 3 :(得分:0)

当然有。对于要创建的目标类,最初需要一个java.lang.Class实例。根据您的结构,这可能由调用者传入(如果他们提供他们想要创建的具体类),或者您可以静态访问类变量(例如MyFooImpl.class)。

最简单的方法是致电Class.newInstance()。这将调用默认的no-arg构造函数(假设该类有一个;如果不是,则抛出异常)。

如果需要使用某个参数调用特定构造函数,则需要调用Class.getConstructor()以获取构造函数实例,然后可以调用newInstance

在所有情况下,您都需要处理直接调用构造函数时无法获得的反射异常。

大编辑:我假设您的问题是通过反射创建类的实例。但是我开始认为你在运行时询问定义新类。如果是这样,那么反射在这里不会帮助你 - 你需要以编程方式调用编译器,我相信可以这样做,但我不是100%的细节。我想你也必须通过一些箍来让ClassLoader接收你的新课程。

答案 4 :(得分:0)

您可以使用Janino创建源代码字符串并将其编译为类文件。

答案 5 :(得分:0)

正如人们已经提到的那样,没有办法在运行时使用反射创建新类。我知道的一个库被不同的模拟库和类似库使用cglib

答案 6 :(得分:0)

你可以使用javassist。这是sudo代码

        javassist.ClassPool pool = new ClassPool(true); 
        CtClass bclass = pool.makeClass("brandnewclass);
        bclass.addConstructor(CtNewConstructor.defaultConstructor(bclass));
        CtClass[] fieldclasses = new CtClass[fields.length];
        CtClass serClass = pool.get(Serializable.class.getName());
        bclass.addInterface(serClass);

Class clazz = pool.loadClass(“className”); obj = clazz.newInstance();

使用反射从现有类中提取值并将值分配给新类。 希望这可以帮助。 戈皮