简体   繁体   English

如何在java中动态创建一个类

[英]How to create a class dynamically in java

I don't know if this is even possible.我不知道这是否可能。 Anyway, here is my problem: I want to create a Class having a database table schema, for example suppose that I have a table like无论如何,这是我的问题:我想创建一个具有数据库表架构的类,例如假设我有一个像

id - unsigned int 
username - varchar(128)
password - varchar(128)

and let's assume I can query this data from my db.假设我可以从我的数据库中查询这些数据。 What I want to do is to dynamically create (and, of course, instantiate) a Java class that should look like this:我想要做的是动态创建(当然还有实例化)一个应该如下所示的 Java 类:

public class User{
    private unsigned int id;
    private String username;
    private String password;
}

(actually an ActiveRecord for my table) (实际上是我表的ActiveRecord

Can you help me starting this?你能帮我开始吗? Tnks坦克

What would you do with a dynamically created and instantiated class that none of your other code knows about?你会用一个你的其他代码都不知道的动态创建和实例化的类来做什么?

For a stically typed language like Java, it makes little sense to have such classes.对于像 Java 这样的静态类型语言,拥有这样的类毫无意义。 On the other hand, most OR Mappers like Hibernate come with tools that allow you to statically generate classes from a database schema.另一方面,像 Hibernate 这样的大多数 OR 映射器都带有允许您从数据库模式静态生成类的工具。

Technically, you can, via a bytecode manipulation library - CGLIB, javassist, asm, bcel and the likes.从技术上讲,您可以通过字节码操作库 - CGLIB、javassist、asm、bcel 等。

However, this is not the Java "philosophy".然而,这不是 Java 的“哲学”。 Java is statically-typed, so you'd better create the classes before runtime. Java 是静态类型的,因此您最好在运行之前创建类。

Take a look at hibernate / eclipseLink for Java ORM - a way of mapping tables to objects.看看 Java ORM 的hibernate / eclipseLink - 一种将表映射到对象的方法。

我想你想要的是java.lang.reflect.Proxy和相关类提供的工具。

This is a good article to start with, but are you sure you need to actually create a new class?是一篇很好的文章开始,但您确定需要实际创建一个新类吗? Maybe you could just use a Map?也许你可以只使用地图?

Like @Bozho states, Java is a statically typed language for which generating classes at runtime can only lead to mayhem.就像@Bozho 所说的那样,Java 是一种静态类型语言,在运行时生成类只会导致混乱。

In our world, it is far more convenient to generate classes at build time, that's to say during compilation.在我们的世界中,在构建时生成类要方便得多,也就是说在编译期间。 Typycally, using Hibernate reverse engineering , you can build your Java classes from your DB schema at build time, and deploy those classes in your application, which give you authentical Java code to read, with the guarantee that your code will be bound to your DB schema通常,使用Hibernate 逆向工程,您可以在构建时从您的 DB 模式构建您的 Java 类,并将这些类部署到您的应用程序中,这为您提供真实的 Java 代码以供阅读,并保证您的代码将绑定到您的数据库模式

The Article about the "new" Compiler API and the java doc for JavaCompiler show a way on how to compile java source from String objects. 该条款对“新”的编译器API,为Java文档JavaCompiler展示如何编译java源从方式String对象。 (I don't know if we can compile to output streams and load the class files in memory yet...) (我不知道我们是否可以编译为输出流并将类文件加载到内存中...)

You can load the class files later on with a URLClassLoader and create instances (reclection/invocation API)您可以稍后使用URLClassLoader加载类文件并创建实例(记录/调用 API)

Here is one nice CGLib-based solution:这是一个不错的基于 CGLib 的解决方案:

http://code.google.com/p/cglib-wrappers/wiki/Wrappers http://code.google.com/p/cglib-wrappers/wiki/Wrappers

Yes, its possible to compile classes at run time.是的,可以在运行时编译类。 I've done it before in Genetic Algorithms research.我之前在遗传算法研究中做过。 Its possible using the built in interface to the compiler.它可以使用编译器的内置接口。 An article over at Java World describes the basic approach: http://www.javaworld.com/javaworld/jw-06-2006/jw-0612-dynamic.html?page=3 Java World 上的一篇文章描述了基本方法: http : //www.javaworld.com/javaworld/jw-06-2006/jw-0612-dynamic.html?page=3

You could generate Java source text and use javax.tools package to compile it and a class loader to load it.您可以生成 Java 源文本并使用 javax.tools 包来编译它并使用类加载器来加载它。 Googling yields some examples how it can be done, but I never tried anything like that, so I don't know what problems you may encounter.谷歌搜索产生了一些如何完成的例子,但我从未尝试过这样的事情,所以我不知道你可能会遇到什么问题。 Clearly, Java wasn't designed for such things.显然,Java 不是为这些事情而设计的。

Old question and if it is possible, you should avoid to generate class during runtime, but sometimes you have to do that.老问题,如果可能的话,您应该避免在运行时生成类,但有时您必须这样做。 So you can use Javassist and here is example...所以你可以使用Javassist,这里是例子......

I created a small example here: http://hrabosch.com/2018/04/08/generate-class-during-runtime-with-javassist/我在这里创建了一个小例子: http : //hrabosch.com/2018/04/08/generate-class-during-runtime-with-javassist/

But here is main point:但这里是要点:

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();
}

So what I did... Via Javassist I made a class in ClassPool.所以我做了什么......通过Javassist我在ClassPool中创建了一个类。 Also I added a method inside this class and via reflection I invoked it.我还在这个类中添加了一个方法,并通过反射调用了它。

Hope it helps.希望能帮助到你。

Just keep on mind whatever you want to use in generated class, there are NOT imports, so you have to use fully-qualified names.请记住,无论您想在生成的类中使用什么,都没有导入,因此您必须使用完全限定的名称。

I suppose the end goal is to have ActiveRecord- like code to write DB access.我想最终目标是使用类似 ActiveRecord 的代码来编写 DB 访问。 If that is the case, you can take a look at Java implementation of ActiveRecord: http://code.google.com/p/activejdbc/如果是这种情况,您可以查看 ActiveRecord 的 Java 实现: http : //code.google.com/p/activejdbc/

cheers,干杯,

igor伊戈尔

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM