public void addConstructor(Constructor<?> constructor) throws Exception { List<Type> paramTypes = new ArrayList<Type>(); for (Class<?> paramType : constructor.getParameterTypes()) { paramTypes.add(Type.getType(paramType)); } String methodDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, paramTypes.toArray(new Type[paramTypes.size()])); String signature = signature(constructor); MethodVisitor methodVisitor = visitor.visitMethod( Opcodes.ACC_PUBLIC, "<init>", methodDescriptor, signature, new String[0]); methodVisitor.visitCode(); // this.super(p0 .. pn) methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); for (int i = 0; i < constructor.getParameterTypes().length; i++) { methodVisitor.visitVarInsn( Type.getType(constructor.getParameterTypes()[i]).getOpcode(Opcodes.ILOAD), i + 1); } methodVisitor.visitMethodInsn( Opcodes.INVOKESPECIAL, superclassType.getInternalName(), "<init>", methodDescriptor); if (initDynamicObjectHelper != null) { initDynamicObjectHelper.add(methodVisitor); } if (initConventionAwareHelper != null) { initConventionAwareHelper.add(methodVisitor); } if (initMetaClass != null) { initMetaClass.add(methodVisitor); } methodVisitor.visitInsn(Opcodes.RETURN); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); }
/** Generates the signature for the given constructor */ private String signature(Constructor<?> constructor) { StringBuilder builder = new StringBuilder(); if (constructor.getTypeParameters().length > 0) { builder.append('<'); for (TypeVariable<?> typeVariable : constructor.getTypeParameters()) { builder.append(typeVariable.getName()); for (java.lang.reflect.Type bound : typeVariable.getBounds()) { builder.append(':'); visitType(bound, builder); } } builder.append('>'); } builder.append('('); for (java.lang.reflect.Type paramType : constructor.getGenericParameterTypes()) { visitType(paramType, builder); } builder.append(")V"); for (java.lang.reflect.Type exceptionType : constructor.getGenericExceptionTypes()) { builder.append('^'); visitType(exceptionType, builder); } return builder.toString(); }