/** 用于更新类名。 */
 public void visit(
     final int version,
     final int access,
     final String name,
     final String signature,
     final String superName,
     final String[] interfaces) {
   // 1.类名
   this.superClassName = name;
   String className = this.classConfig.getClassName();
   className = classConfig.getClassName().replace(".", "/");
   // 2.确定接口
   Set<String> newFaces = new HashSet<String>();
   for (String faces : interfaces) {
     newFaces.add(faces);
   }
   InnerMethodDelegateDefine[] defineArrays = this.classConfig.getNewDelegateList();
   for (InnerMethodDelegateDefine define : defineArrays) {
     Class<?> faceType = define.getFaces();
     newFaces.add(ASMEngineTools.replaceClassName(faceType));
   }
   String[] finalInterfaces = newFaces.toArray(new String[newFaces.size()]);
   //
   super.visit(version, access, className, signature, name, finalInterfaces);
 }
 private void visitConstruction(MethodVisitor mv, String name, String desc) {
   // 1.准备输出方法数据
   Pattern p = Pattern.compile("\\((.*)\\)(.*)");
   Matcher m = p.matcher(desc);
   m.find();
   String[] asmParams =
       ASMEngineTools.splitAsmType(
           m.group(1)); // "IIIILjava/lang/Integer;F[[[ILjava/lang.Boolean;"
   int paramCount = asmParams.length;
   //
   mv.visitVarInsn(ALOAD, 0);
   for (int i = 0; i < paramCount; i++) {
     String asmType = asmParams[i];
     mv.visitVarInsn(ASMEngineTools.getLoad(asmType), i + 1);
   }
   mv.visitMethodInsn(INVOKESPECIAL, this.superClassName, name, desc);
   mv.visitInsn(RETURN);
   mv.visitMaxs(paramCount + 1, paramCount + 1);
 }
 public void visitEnd() {
   InnerMethodDelegateDefine[] defineArrays = this.classConfig.getNewDelegateList();
   for (InnerMethodDelegateDefine define : defineArrays) {
     Class<?> faceType = define.getFaces();
     Method[] faceMethods = faceType.getMethods();
     for (Method tMethod : faceMethods) {
       String mName = tMethod.getName();
       String typeDesc =
           String.format("%s(%s)", mName, ASMEngineTools.toAsmType(tMethod.getParameterTypes()));
       //
       if (this.validMethod.contains(typeDesc) == false) {
         String desc = ASMEngineTools.toAsmDesc(tMethod);
         MethodVisitor mv = super.visitMethod(ACC_PUBLIC, mName, desc, null, null);
         mv.visitCode();
         this.buildInterfaceMethod(mv, mName, desc, faceType);
         mv.visitEnd();
       }
       //
     }
     //
   }
   super.visitEnd();
 }
 // Code Builder “return ...”
 private void codeBuilder_3(MethodVisitor mv, String asmReturns) {
   if (asmReturns.equals("B") == true) {
     mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Byte");
     mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B");
     mv.visitInsn(ASMEngineTools.getReturn("B"));
   } else if (asmReturns.equals("S") == true) {
     mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Short");
     mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S");
     mv.visitInsn(ASMEngineTools.getReturn("S"));
   } else if (asmReturns.equals("I") == true) {
     mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Integer");
     mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I");
     mv.visitInsn(ASMEngineTools.getReturn("I"));
   } else if (asmReturns.equals("J") == true) {
     mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Long");
     mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J");
     mv.visitInsn(ASMEngineTools.getReturn("J"));
   } else if (asmReturns.equals("F") == true) {
     mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Float");
     mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F");
     mv.visitInsn(ASMEngineTools.getReturn("F"));
   } else if (asmReturns.equals("D") == true) {
     mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Double");
     mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D");
     mv.visitInsn(ASMEngineTools.getReturn("D"));
   } else if (asmReturns.equals("C") == true) {
     mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Character");
     mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C");
     mv.visitInsn(ASMEngineTools.getReturn("C"));
   } else if (asmReturns.equals("Z") == true) {
     mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Boolean");
     mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z");
     mv.visitInsn(ASMEngineTools.getReturn("Z"));
   } else if (asmReturns.equals("V") == true) {
     mv.visitInsn(Opcodes.POP);
     mv.visitInsn(Opcodes.RETURN);
   } else {
     mv.visitTypeInsn(Opcodes.CHECKCAST, ASMEngineTools.asmTypeToType(asmReturns));
     mv.visitInsn(Opcodes.ARETURN);
   }
 }
 //
 // Code Builder “new Object[] { abc, abcc, abcc };”
 private void codeBuilder_1(MethodVisitor mv, String[] asmParams) {
   int paramCount = asmParams.length;
   mv.visitIntInsn(Opcodes.BIPUSH, paramCount);
   mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
   for (int i = 0; i < paramCount; i++) {
     String asmType = asmParams[i];
     mv.visitInsn(Opcodes.DUP);
     mv.visitIntInsn(Opcodes.BIPUSH, i);
     if (asmParams[i].equals("B") == true) {
       mv.visitVarInsn(ASMEngineTools.getLoad(asmType), i + 1);
       mv.visitMethodInsn(
           Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;");
     } else if (asmParams[i].equals("S") == true) {
       mv.visitVarInsn(ASMEngineTools.getLoad(asmType), i + 1);
       mv.visitMethodInsn(
           Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;");
     } else if (asmParams[i].equals("I") == true) {
       mv.visitVarInsn(ASMEngineTools.getLoad(asmType), i + 1);
       mv.visitMethodInsn(
           Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
     } else if (asmParams[i].equals("J") == true) {
       mv.visitVarInsn(ASMEngineTools.getLoad(asmType), i + 1);
       mv.visitMethodInsn(
           Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;");
     } else if (asmParams[i].equals("F") == true) {
       mv.visitVarInsn(ASMEngineTools.getLoad(asmType), i + 1);
       mv.visitMethodInsn(
           Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;");
     } else if (asmParams[i].equals("D") == true) {
       mv.visitVarInsn(ASMEngineTools.getLoad(asmType), i + 1);
       mv.visitMethodInsn(
           Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;");
     } else if (asmParams[i].equals("C") == true) {
       mv.visitVarInsn(ASMEngineTools.getLoad(asmType), i + 1);
       mv.visitMethodInsn(
           Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;");
     } else if (asmParams[i].equals("Z") == true) {
       mv.visitVarInsn(ASMEngineTools.getLoad(asmType), i + 1);
       mv.visitMethodInsn(
           Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;");
     } else {
       mv.visitVarInsn(Opcodes.ALOAD, i + 1);
     }
     mv.visitInsn(Opcodes.AASTORE);
   }
 }
 // 实现接口附加
 private void buildInterfaceMethod(MethodVisitor mv, String name, String desc, Class<?> faceType) {
   // 例子代码
   //    public int getNames(int abc, Object abcc) {
   //        try {
   //            Class<?>[] arrayOfClass = new Class[] { int.class, Object.class };
   //            Object[] arrayOfObject = new Object[] { abc, abcc };
   //            //
   //            Method localMethod = List.class.getMethod("getNames", arrayOfClass);
   //            ClassLoader localLoader = getClass().getClassLoader();
   //            //
   //            Object target = new InnerChainMethodDelegate("xxxx",
   // localLoader).invoke(localMethod, this, arrayOfObject);
   //            return ((Integer) target).intValue();
   //        } catch (Throwable e) {
   //            throw new RuntimeException(e);
   //        }
   //    }
   // 1.准备输出方法数据
   Pattern p = Pattern.compile("\\((.*)\\)(.*)");
   Matcher m = p.matcher(desc);
   m.find();
   String[] asmParams =
       ASMEngineTools.splitAsmType(
           m.group(1)); // "IIIILjava/lang/Integer;F[[[ILjava/lang.Boolean;"
   String asmReturns = m.group(2);
   int paramCount = asmParams.length;
   int maxStack = 4; // 方法最大堆栈大小
   int maxLocals = paramCount + 5; // 本地变量表大小
   //
   Label tryBegin = new Label();
   Label tryEnd = new Label();
   Label tryCatch = new Label();
   mv.visitTryCatchBlock(tryBegin, tryEnd, tryCatch, "java/lang/Throwable");
   { // try {
     mv.visitLabel(tryBegin);
     // Class<?>[] pTypes = new Class[] { int.class, Object.class, boolean.class, short.class };
     this.codeBuilder_2(mv, asmParams);
     mv.visitVarInsn(ASTORE, paramCount + 2);
     // Object[] pObjects = new Object[] { abc, abcc, abcc };
     this.codeBuilder_1(mv, asmParams);
     mv.visitVarInsn(ASTORE, paramCount + 3);
     //
     // List.class.getMethod("getNames", arrayOfClass);
     mv.visitLdcInsn(Type.getType(ASMEngineTools.toAsmType(faceType)));
     mv.visitLdcInsn(name);
     mv.visitVarInsn(ALOAD, paramCount + 2);
     mv.visitMethodInsn(
         INVOKEVIRTUAL,
         "java/lang/Class",
         "getMethod",
         "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;");
     mv.visitVarInsn(ASTORE, paramCount + 4);
     //
     // ClassLoader localLoader = getClass().getClassLoader();
     mv.visitVarInsn(ALOAD, 0);
     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
     mv.visitMethodInsn(
         INVOKEVIRTUAL, "java/lang/Class", "getClassLoader", "()Ljava/lang/ClassLoader;");
     mv.visitVarInsn(ASTORE, paramCount + 5);
     //
     // Object target = new InnerChainMethodDelegate("xxxx", localLoader).invoke(localMethod, this,
     // arrayOfObject);
     mv.visitTypeInsn(NEW, ASMEngineTools.replaceClassName(InnerChainMethodDelegate.class));
     mv.visitInsn(DUP);
     mv.visitLdcInsn(this.classConfig.getClassName());
     mv.visitLdcInsn(faceType.getName());
     mv.visitVarInsn(ALOAD, paramCount + 5);
     mv.visitMethodInsn(
         INVOKESPECIAL,
         ASMEngineTools.replaceClassName(InnerChainMethodDelegate.class),
         "<init>",
         "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V");
     mv.visitVarInsn(ALOAD, paramCount + 4);
     mv.visitVarInsn(ALOAD, 0);
     mv.visitVarInsn(ALOAD, paramCount + 3);
     mv.visitMethodInsn(
         INVOKEVIRTUAL,
         ASMEngineTools.replaceClassName(InnerChainMethodDelegate.class),
         "invoke",
         "(Ljava/lang/reflect/Method;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
     mv.visitVarInsn(ASTORE, paramCount + 6);
     //
     // return
     mv.visitVarInsn(ALOAD, paramCount + 6);
     mv.visitLabel(tryEnd);
     this.codeBuilder_3(mv, asmReturns);
   }
   { // } catch (Exception e) {
     mv.visitLabel(tryCatch);
     mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
     mv.visitVarInsn(ASTORE, 5);
     mv.visitVarInsn(ALOAD, 5);
     mv.visitTypeInsn(INSTANCEOF, "java/lang/RuntimeException");
     Label ifBlock = new Label();
     mv.visitJumpInsn(IFEQ, ifBlock);
     mv.visitVarInsn(ALOAD, 5);
     mv.visitTypeInsn(CHECKCAST, "java/lang/RuntimeException");
     mv.visitInsn(ATHROW);
     mv.visitLabel(ifBlock);
     mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"java/lang/Throwable"}, 0, null);
     mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
     mv.visitInsn(DUP);
     mv.visitVarInsn(ALOAD, 5);
     mv.visitMethodInsn(
         INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/Throwable;)V");
     mv.visitInsn(ATHROW);
     mv.visitMaxs(maxStack, maxLocals);
   } // }
 }