我不知道这是否可行。无论如何,这是我的问题: 我想创建一个具有数据库表模式的类,例如假设我有一个像
这样的表id - unsigned int
username - varchar(128)
password - varchar(128)
我们假设我可以从我的数据库中查询这些数据。我想要做的是动态创建(当然,实例化)一个看起来像这样的Java类:
public class User{
private unsigned int id;
private String username;
private String password;
}
(实际上我的桌子是ActiveRecord
)
答案 0 :(得分:19)
您将使用动态创建并实例化的类(您的其他代码都不知道)做什么?
对于像Java这样的静态类型语言,拥有这样的类是没有意义的。另一方面,像Hibernate这样的大多数OR Mappers都带有允许您从数据库模式静态生成类的工具。
答案 1 :(得分:17)
从技术上讲,你可以通过字节码操作库 - CGLIB,javassist,asm,bcel等。
然而,这不是Java的“哲学”。 Java是静态类型的,因此您最好在运行时之前创建类。
查看{ORM的hibernate / eclipseLink - 一种将表映射到对象的方法。
答案 2 :(得分:6)
我认为你想要的是java.lang.reflect.Proxy
及相关课程提供的设施。
答案 3 :(得分:4)
This是一篇很好的文章,但你确定你需要真正创建一个新类吗?也许你可以使用Map?
答案 4 :(得分:1)
与@Bozho状态一样,Java是一种静态类型语言,在运行时生成类只会导致混乱。
在我们的世界中,在构建时生成类更方便,也就是说在编译期间。使用Hibernate reverse engineering,您可以在构建时从数据库模式构建Java类,并在应用程序中部署这些类,从而为您提供真实的Java代码,并保证您的代码将被绑定到您的数据库架构
答案 5 :(得分:1)
The Article关于“新”编译器API和JavaCompiler
的java文档显示了如何从String
对象编译java源代码的方法。 (我不知道我们是否可以编译输出流并将类文件加载到内存中......)
您可以稍后使用URLClassLoader
加载类文件并创建实例(reclection / invocation API)
答案 6 :(得分:0)
是的,可以在运行时编译类。我之前在遗传算法研究中做过。它可以使用编译器的内置接口。 Java World上的一篇文章介绍了基本方法:http://www.javaworld.com/javaworld/jw-06-2006/jw-0612-dynamic.html?page=3
答案 7 :(得分:0)
您可以生成Java源文本并使用javax.tools包进行编译,并使用类加载器加载它。谷歌搜索提供了一些如何做到的例子,但我从未尝试过这样的事情,所以我不知道你可能会遇到什么问题。显然,Java并不是为这些东西设计的。
答案 8 :(得分:0)
我认为最终目标是使用类似ActiveRecord的代码来编写数据库访问。如果是这种情况,您可以查看ActiveRecord的Java实现: http://code.google.com/p/activejdbc/
欢呼声,
伊戈尔
答案 9 :(得分:0)
这是一个很好的基于CGLib的解决方案:
答案 10 :(得分:0)
旧问题,如果有可能,你应该避免在运行时生成类,但有时你必须这样做。所以你可以使用Javassist,这里是例子......
我在这里创建了一个小例子:http://hrabosch.com/2018/04/08/generate-class-during-runtime-with-javassist/
但这是重点:
public static Class generateClass(String className, String methodName, String methodBody)
throws CannotCompileException {
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.makeClass(className);
StringBuffer method = new StringBuffer();
method.append("public void ")
.append(methodName)
.append("() {")
.append(methodBody)
.append(";}");
cc.addMethod(CtMethod.make(method.toString(), cc));
return cc.toClass();
}
所以我做了...通过Javassist我在ClassPool中创建了一个类。我还在这个类中添加了一个方法,并通过反射调用它。
希望它有所帮助。
请记住要在生成的类中使用的任何内容 不是导入,因此您必须使用完全限定名称。