Em primeiro lugar, você deve criar a matriz de bytes (= conteúdo no arquivo .class) com ClassWriter.
private byte[] createClassBinary() {
ClassWriter cw = new ClassWriter(0);
cw.visit(V1_5, ACC_PUBLIC, "pkg/OwnClass", null, "java/lang/Object", null);
{
// constructor
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitMaxs(2, 1);
mv.visitVarInsn(ALOAD, 0); // push `this` to the operand stack
mv.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(Object.class), "<init>", "()V"); // call the constructor of super class
mv.visitInsn(RETURN);
mv.visitEnd();
}
{
// public Object get() { return new Object(); }
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "get", "()Ljava/lang/Object;", null, null);
mv.visitMaxs(2, 1);
mv.visitTypeInsn(NEW, Type.getInternalName(Object.class));
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(Object.class), "<init>", "()V");
mv.visitInsn(ARETURN);
mv.visitEnd();
}
cw.visitEnd();
return cw.toByteArray();
}
Em seguida, você pode criar uma instância de classe a partir desta matriz de bytes. Você deve criar o carregador de classes original e chamar seu método #defineClass.
private static class OwnClassLoader extends ClassLoader {
public Class<?> defineClass(String name, byte[] b) {
return defineClass(name, b, 0, b.length);
}
}
private Class<?> createClass(byte[] b) {
return new OwnClassLoader().defineClass("pkg.OwnClass", b);
}