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:
public class User{
private unsigned int id;
private String username;
private String password;
}
(actually an ActiveRecord
for m开发者_运维技巧y table)
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. On the other hand, most OR Mappers like Hibernate come with tools that allow you to statically generate classes from a database schema.
Technically, you can, via a bytecode manipulation library - CGLIB, javassist, asm, bcel and the likes.
However, this is not the Java "philosophy". Java is statically-typed, so you'd better create the classes before runtime.
Take a look at hibernate / eclipseLink for Java ORM - a way of mapping tables to objects.
I think what you want is the facility provided by java.lang.reflect.Proxy
and related classes.
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.
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
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. (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)
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
You could generate Java source text and use javax.tools package to compile it and a class loader to load it. 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.
Here is one nice CGLib-based solution:
http://code.google.com/p/cglib-wrappers/wiki/Wrappers
I suppose the end goal is to have ActiveRecord- like code to write DB access. If that is the case, you can take a look at Java implementation of ActiveRecord: http://code.google.com/p/activejdbc/
cheers,
igor
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...
I created a small example here: 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. 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.
精彩评论