在 Java 中,是否可以在应用程序运行时动态创建类定义,然后创建该类的对象?
例如,一个正在运行的应用程序将读入一个文本文件,该文件包含要包含在新类中的类成员列表。然后,应用程序将根据成员列表定义一个类定义,然后实例化它。
在 Java 中,是否可以在应用程序运行时动态创建类定义,然后创建该类的对象?
例如,一个正在运行的应用程序将读入一个文本文件,该文件包含要包含在新类中的类成员列表。然后,应用程序将根据成员列表定义一个类定义,然后实例化它。
是的,理论上可以这样做,您的类文件是字节码,最后是字节数组!然后,您可以使用方法 defineClass(String, byte[], int, int) 来获取可用于通过反射实例化对象的 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。
最近有一个关于内存编译的问题,它应该会给你一些提示,告诉你在你设法生成源代码后该做什么。