有没有一种方法可以使用java反射api在运行时创建java类@(classes methods n variables)
qgzx9mmu1#
正如人们已经提到的,在运行时使用反射无法创建新类。我知道有一个库被不同的mocking库使用,比如cglib。
x8diyxa72#
你不能用反射来做。您需要一个字节码操作库,比如jakarta bcel。
6qfn3psc3#
标准javaapi提供了一组静态方法,允许您动态创建实现一个(或多个)接口的类。这些方法是java.lang.reflect.proxy类的一部分。
i2loujxw4#
当然有。对于要创建的目标类,最初需要一个java.lang.class示例。根据您的结构,这可能由调用者传入(如果他们提供想要创建的具体类),或者您可以静态地访问类变量(例如。 MyFooImpl.class ).最简单的方法是调用class.newinstance()。这将调用默认的no-arg构造函数(假设类有一个构造函数;否则会引发异常)。如果需要使用某个参数调用特定的构造函数,则需要调用class.getconstructor()来获取构造函数示例,然后可以对其调用newinstance。在所有情况下,您都需要处理反射异常,如果直接调用构造函数,您将无法得到这些异常。大编辑:我假设你的问题是关于通过反射创建类的示例。不过,我开始认为您正在询问如何在运行时通过定义新类。如果是这样,那么反射在这里就帮不了你——你需要用编程的方式调用一个编译器,我相信这是可以做到的,但我不是百分之百地关注细节。我想你还得经历一些困难,才能让类加载器也来上你的新课。
MyFooImpl.class
5cg8jx4n5#
您可以创建源代码字符串并使用janino将其编译为类文件。
brvekthn6#
你要这个干什么?我可以想出四种可能的选择。如果你有一个类,你也添加了一些东西,你可能会发现面向方面的编程是你真正想要的。如果您有一个要动态实现的接口(如barjak所发布的),那么您需要的是 java.lang.reflect.Proxy . 这不允许在运行时创建“代码”,而是允许将现有代码链接到接口。最后(据我所知)您实际上已经在运行时构建了随机类。这需要cglib或bcel之类的东西。虽然在有些情况下,这是必要的,但在国际海事组织是罕见的。另一个选择是,您并不真正需要运行时,而是需要构建时间。在这种情况下,您可以使用注解和 apt (java 5)/ Processor (java 6)。
java.lang.reflect.Proxy
apt
Processor
rjzwgtxy7#
您可以使用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(“类名”);obj=clazz.newinstance();使用反射从现有类中提取值并将值赋给新类。希望这有帮助。戈皮
7条答案
按热度按时间qgzx9mmu1#
正如人们已经提到的,在运行时使用反射无法创建新类。我知道有一个库被不同的mocking库使用,比如cglib。
x8diyxa72#
你不能用反射来做。您需要一个字节码操作库,比如jakarta bcel。
6qfn3psc3#
标准javaapi提供了一组静态方法,允许您动态创建实现一个(或多个)接口的类。这些方法是java.lang.reflect.proxy类的一部分。
i2loujxw4#
当然有。对于要创建的目标类,最初需要一个java.lang.class示例。根据您的结构,这可能由调用者传入(如果他们提供想要创建的具体类),或者您可以静态地访问类变量(例如。
MyFooImpl.class
).最简单的方法是调用class.newinstance()。这将调用默认的no-arg构造函数(假设类有一个构造函数;否则会引发异常)。
如果需要使用某个参数调用特定的构造函数,则需要调用class.getconstructor()来获取构造函数示例,然后可以对其调用newinstance。
在所有情况下,您都需要处理反射异常,如果直接调用构造函数,您将无法得到这些异常。
大编辑:我假设你的问题是关于通过反射创建类的示例。不过,我开始认为您正在询问如何在运行时通过定义新类。如果是这样,那么反射在这里就帮不了你——你需要用编程的方式调用一个编译器,我相信这是可以做到的,但我不是百分之百地关注细节。我想你还得经历一些困难,才能让类加载器也来上你的新课。
5cg8jx4n5#
您可以创建源代码字符串并使用janino将其编译为类文件。
brvekthn6#
你要这个干什么?
我可以想出四种可能的选择。
如果你有一个类,你也添加了一些东西,你可能会发现面向方面的编程是你真正想要的。
如果您有一个要动态实现的接口(如barjak所发布的),那么您需要的是
java.lang.reflect.Proxy
. 这不允许在运行时创建“代码”,而是允许将现有代码链接到接口。最后(据我所知)您实际上已经在运行时构建了随机类。这需要cglib或bcel之类的东西。虽然在有些情况下,这是必要的,但在国际海事组织是罕见的。
另一个选择是,您并不真正需要运行时,而是需要构建时间。在这种情况下,您可以使用注解和
apt
(java 5)/Processor
(java 6)。rjzwgtxy7#
您可以使用javassist。这是sudo代码
class clazz=pool.loadclass(“类名”);obj=clazz.newinstance();
使用反射从现有类中提取值并将值赋给新类。希望这有帮助。戈皮