在Java应用程序运行时定义类

在Java中,是否可以在应用程序运行时动态创建类定义,然后创建该类的对象?

例如,正在运行的应用程序将读入一个文本文件,该文件包含要包含在新类中的类成员列表。 然后,应用程序将根据成员列表定义类定义,然后对其进行实例化。

是的,理论上你可以这样做,你的类文件是字节代码,最后是一个字节数组! 然后,您可以使用方法defineClass(String,byte [],int,int)来获取可用于通过reflection实例化对象的Class实例。

在实践中,您可以使用CGLib或javaassist之类的东西。

您还可以使用在文件中生成Java代码,调用编译器,然后加载文件的漫长方法。

您可以使用ASM动态生成类

您可以通过将新类的代码写入文件,然后在该文件上调用Java编译器并使用类加载器将该类动态加载到正在运行的应用程序中来完成此操作。 Apache Tomcat为其JSP页面执行此操作; 它接受代码,对其进行一些更改,将其包装在类中间的try / catch块中,然后将其写入文件系统,编译它,并使用类加载器来获取并起诉它来处理请求。

当然有可能。 例如,参见本文 。

也许最简单的解决方案(就不需要额外的库而言)将使用Java 6附带的Java编译器API 。您只需能够生成.java,编译然后执行Class.forName()。

也许有点矫枉过正, Apache BCEL (字节代码工程库)可用于在运行时创建class文件。

虽然我自己没有尝试过,但可以想象,然后可以创建一个类,加载它,并在运行时实例化它。

是的,这是可能的。

您可以通过定义类的主体并使javassist编译新类来在运行时使用Javassist创建类。

Javassist有一个自定义编译器,可以根据类的定义创建字节码。 它有一些特殊的方法来处理事情,但使用这个库非常容易和直观。

Javassist用于JBoss,我认为这是一个很好的参考:)

使用BCEL可以实现同样的目标,但它更难(但通过这种方式,您可以更好地控制生成的内容)。

如果必须的话,你可以使用JRuby或JPython或Groovy做类似的事情。

如果你感觉特别自虐,你可以看看BCEL 。

如果您想要Java和元编程,请使用Groovy 。

我想, ASM是Java的最低级字节码库。 这使它变得非常困难但也非常强大。 我建议阅读ASM的文档( PDF ),以真正了解Java中字节码生成的工作原理。 该文档还解释了如何在类加载器中加载字节码(另一个难以正确的主题)。

之后,您可以使用其中一个更高级别的库,如果它让您的生活更轻松,并了解他们的工作。 对于许多情况,例如生成代理, CGLIB很有用且易于使用。 为了获得更多function,许多人都提到了Javassist (我还没有使用过它 – CGLIB和ASM对我有好处)。

这里最近有一个关于内存中编译的问题 ,它应该为你提供一些关于在你设法生成源代码之后要做什么的提示。