// (b) copy-constructor which takes StdValueInstantiator instance, passes to superclass
final String optimizedValueInstDesc = Type.getDescriptor(OptimizedValueInstantiator.class);
final String stdValueInstDesc = Type.getDescriptor(StdValueInstantiator.class);
// default (no-arg) constructor:
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, superClass, "<init>", "()V");
mv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
// then single-arg constructor
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "("+stdValueInstDesc+")V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKESPECIAL, superClass, "<init>", "("+stdValueInstDesc+")V");
mv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
// and then non-static factory method to use second constructor (implements base-class method)
// protected abstract OptimizedValueInstantiator with(StdValueInstantiator src);
mv = cw.visitMethod(ACC_PUBLIC, "with", "("
+stdValueInstDesc+")"+optimizedValueInstDesc, null, null);
mv.visitCode();
mv.visitTypeInsn(NEW, generatedClass);
mv.visitInsn(DUP);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKESPECIAL, generatedClass, "<init>", "("+stdValueInstDesc+")V");
mv.visitInsn(ARETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
// And then override: public Object createUsingDefault()
mv = cw.visitMethod(ACC_PUBLIC, "createUsingDefault", "()Ljava/lang/Object;", null, null);
mv.visitCode();
if (ctor != null) {
addCreator(mv, ctor);
} else {
addCreator(mv, factory);
}
mv.visitInsn(ARETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
cw.visitEnd();
return cw.toByteArray();
}