在Java中,是否可以在应用程序运行时动态创建类定义,然后创建该类的对象?例如,正在运行的应用程序将读取包含要包括在新类中的成员列表的文本文件。然后,应用程序将根据成员列表定义一个类定义,接着实例化它。
理论上来说是可以做到的,因为你的类文件最终是一个字节数组!你可以使用 defineClass(String, byte[], int, int) 方法获取一个 Class 实例,然后通过反射实例化对象。 在实际应用中,你可以使用类似 CGLib 或 javaassist 的工具。 你也可以采取生成 Java 代码文件、调用编译器、加载文件的繁琐方式。
你可以通过将新类的代码写入文件,然后在该文件上调用Java编译器,并使用类加载器动态加载该类到正在运行的应用程序中来实现此操作。Apache Tomcat对其JSP页面执行此操作;它获取代码,对其进行一些更改,在类的中间包装一个try/catch块,然后将其写入文件系统,编译它,并使用类加载器获取并使用它来处理请求。
ASM 可能是 Java 最低层次的字节码库。这使得它非常困难,但也非常强大。我建议阅读 ASM 的文档 (PDF),以真正理解 Java 中的字节码生成方式。该文档还解释了如何在类加载器中加载字节码(另一个难点)。 之后,您可以使用其中一个更高级别的库,如果它能让您的生活更轻松,并理解它们所做的事情。对于许多情况,例如生成代理,CGLIB 是有用且易于使用的。对于更强大的功能,许多人提到 Javassist(我没有使用过 - CGLIB 和 ASM 对我来说已经很好了)。
是的,这是可能的。 您可以使用Javassist在运行时创建类,通过定义类的主体并使javassist编译您的新类。 Javassist具有自定义编译器,根据您的类定义创建字节码。它有一些特殊的处理方式,但使用此库非常容易和直观。 Javassist用于JBoss,我认为这是一个很好的参考 :) 同样可以使用BCEL实现相同的功能,但这更加困难(但是以这种方式,您可以更好地控制所生成的内容)。