Java ASM与字节码[bytecode](Version:a

2019-01-16  本文已影响0人  MicoCube
凡是带const的表示将什么数据压操作数栈;如:
iconst_2 将int型数据2压入到操作数栈;
aconst_null  将null值压入栈;
bipush和sipush  表示将单字节或者短整形的常量值压入操作数栈;
带ldc的表示将什么类型数据从常量池中压入到操作数栈;如:
ldc_w  将int或者flat或者string类型的数据压入到操作数栈;
ldc2_w  将long或者double类型的数据压入到操作数栈;
凡是带load的指令表示将某类型的局部变量数据压入到操作数栈的栈顶;如:
iload 表示将int类型的局部变量压入到操作数栈的栈顶;
aload  以a开头的表示将引用类型的局部变量压入到操作数栈的栈顶;
iload_1 将局部变量数组里面下标为1的int类型的数据压入到操作数栈;
iaload   将int型数组的指定索引的值压入到操作数栈;
凡是带有store指令的表示将操作数栈顶的某类型的值存入指定的局部变量中;如:
istore  表示将栈顶int类型的数据存入到指定的局部变量中;
istore_3  表示将栈int类型的数据存入到局部变量数组的下标为3的元素中;
pop  将栈顶数据弹出;pop2将栈顶的一个long或者double数据从栈顶弹出来;
dup  复制栈顶的数据并将复制的值也压入到栈顶;
dup2  复制栈顶一个long或者是double的数据并将复制的值也压入到栈顶;
swap  将栈最顶端的两个值互换;
iadd 将栈顶两个int型的数据相加然后将结果再次的压入到栈顶;
isub 将栈顶两个int型的数据相减然后将结果再次的压入到栈顶;   
imul 将栈顶两个int型的数据相乘然后将结果再次的压入到栈顶;
idiv  将栈顶两个int型的数据相除然后将结果再次的压入到栈顶;
irem 将栈顶两个int型的数据取模运算然后将结果再次的压入到栈顶;
ineg 将栈顶的int数据取负将结果压入到栈顶;
iinc  将指定的int变量增加指定值(i++,i--,i+=2);
i2l   将栈顶int类型数据强制转换成long型将结果压入到栈顶;
lcmp  将栈顶两long型数据的大小进行比较,并将结果(1,0,-1)压入栈顶;
以if开头的指令都是跳转指令;
tableswitch、lookupswitch  表示用switch条件跳转;
ireturn  从当前方法返回int型数据;
getstatic  获取指定类的静态域,将将结果压入到栈顶;
putstatic 为指定的类的静态域赋值;
getfield   获取指定类的实例变量,将结果压入到栈顶;
putfield   为指定类的实例变量赋值;
invokevirtual  调用实例方法;
invokespacial  调用超类构造方法,实例初始化方法,私有方法;
invokestatic  调用静态方法;
invokeinterface  调用接口方法; 
new 创建一个对象,并将其引用压入到栈顶;
newarray  创建一个原始类型的数组,并将其引用压入到栈顶;
arraylength   获得一个数组的长度,将将结果压入到栈顶;
athrow   将栈顶的异常抛出;
checkcast  检验类型转换,转换未通过,将抛出ClassCastException.
instanceof 检验对象是否是指定的类的实例,如果是将1压入栈顶,否则将0压入栈顶 
monitorenter   获得对象的锁,用于同步方法或同步块  
monitorexit    释放对象的锁,用于同步方法或同步块
ifnull    为null时跳转 
ifnonnull   不为null时跳转
package com.coding.asm.test;



import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @Description: 通过ASM生成类的字节码
 */
public class GeneratorClass {

    public static void main(String[] args) throws IOException {

        //①  ClassReader:该类用来解析编译过的class字节码文件。

        //②  ClassWriter:该类用来重新构建编译后的类,比如说修改类名、属性以及方法,甚至可以生成新的类的字节码文件。

        //③  ClassAdapter:该类也实现了ClassVisitor接口,它将对它的方法调用委托给另一个ClassVisitor对象。


        //生成一个类只需要ClassWriter组件即可
        ClassWriter cw = new ClassWriter(0);
        //通过visit方法确定类的头部信息

        //一个编译后的java类不包含package和import段,因此在class文件中所有的类型都使用的是全路径。
        //public final void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
        // version:类版本
        // access:类的访问标识
        // name:类名称
        // signature:类签名,如果类不是通用类,并且不扩展或实现泛型类或接口,则可能为null。
        // superName:超类名称,如果是接口或超类为Object则可能为null
        // interfaces:类实现的接口名称列表
        cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT + Opcodes.ACC_INTERFACE,
                "com/coding/asm/test/GenInterface", null, "java/lang/Object",
                new String[]{"java/lang/Iterable"});

        // 定义类的属性
        // public final FieldVisitor visitField(int access, String name, String desc, String signature, Object value)
        // access:字段访问标识
        // name:字段名称
        // desc:字段描述
        // signature:字段签名,若字段类型不是泛型则可以为null
        // value:字段初始值
        cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC,
                "LESS", "I", null, new Integer(-1)).visitEnd();
        cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC,
                "EQUAL", "I", null, new Integer(0)).visitEnd();
        cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC,
                "GREATER", "I", null, new Integer(1)).visitEnd();
        // 定义类的方法
        // public final MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)
        // access:方法访问标识
        // name:方法名称
        // desc:方法描述
        // signature:方法签名,若方法参数、返回类型和异常没有使用泛型则可能为null
        // exceptions:方法的异常名,可能为null
        cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "compareTo",
                "(Ljava/lang/Object;)I", null, null).visitEnd();
        //使cw类已经完成
        cw.visitEnd();
        //将cw转换成字节数组写到文件里面去
        byte[] data = cw.toByteArray();
        File file = new File("/Users/micocube/Documents/Utils4j/src/main/java/com/coding/asm/test/GenInterface.class");
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(data);
        fos.close();


    }


}
package com.coding.asm.test;
public interface GenInterface extends Iterable {
    int LESS = -1;
    int EQUAL = 0;
    int GREATER = 1;

    int compareTo(Object var1);
}
package com.coding.asm.generator;

import org.objectweb.asm.Opcodes;

public class Header {
    //public final void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
    // version:类版本
    // access:类的访问标识
    // name:类名称
    // signature:类签名,如果类不是通用类,并且不扩展或实现泛型类或接口,则可能为null。
    // superName:超类名称,如果是接口或超类为Object则可能为null
    // interfaces:类实现的接口名称列表
    private int version;
    private int accessModifier = Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL;
    private String className;
    private String plasticity;
    private String superClass;
    private String[] interfaces;

    public Header(int version, int accessModifier, String className, String plasticity, Class superClass, String[] interfaces) {
        this.version = version;
        this.accessModifier = accessModifier;
        this.className = className;
        this.plasticity = plasticity;
        this.superClass = superClass.getName();
        this.interfaces = interfaces;
    }

    public Header(int version, int accessModifier, String className, String plasticity, String superClass, String[] interfaces) {
        this.version = version;
        this.accessModifier = accessModifier;
        this.className = className;
        this.plasticity = plasticity;
        this.superClass = superClass;
        this.interfaces = interfaces;
    }

    public Header(int version, int accessModifier, String className, String plasticity, String[] interfaces) {
        this.version = version;
        this.accessModifier = accessModifier;
        this.className = className;
        this.plasticity = plasticity;
        this.interfaces = interfaces;
    }

    public int getVersion() {
        return version;
    }

    public void setVersion(int version) {
        this.version = version;
    }

    public int getAccessModifier() {
        return accessModifier;
    }

    public void setAccessModifier(int accessModifier) {
        this.accessModifier = accessModifier;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public String getPlasticity() {
        return plasticity;
    }

    public void setPlasticity(String plasticity) {
        this.plasticity = plasticity;
    }

    public String getSuperClass() {
        return superClass;
    }

    public void setSuperClass(String superClass) {
        this.superClass = superClass;
    }

    public String[] getInterfaces() {
        return interfaces;
    }

    public void setInterfaces(String[] interfaces) {
        this.interfaces = interfaces;
    }
}
package com.coding.asm.generator;


import org.objectweb.asm.Type;

public class Field {
    // public final FieldVisitor visitField(int access, String name, String desc, String signature, Object value)
    // access:字段访问标识
    // name:字段名称
    // desc:字段描述
    // signature:字段签名,若字段类型不是泛型则可以为null
    // value:字段初始值

    private int accessModifier;
    private String fieldName;
    private String fieldType;
    private String plasticity;
    private Object initValue;

    public Field(int accessModifier, String fieldName, TypeDescriptor fieldType, String plasticity, Object initValue) {
        this.accessModifier = accessModifier;
        this.fieldName = fieldName;
        this.fieldType = fieldType.getType();
        this.plasticity = plasticity;
        this.initValue = initValue;
    }

    public Field(int accessModifier, String fieldName, TypeDescriptor fieldType, String plasticity) {
        this.accessModifier = accessModifier;
        this.fieldName = fieldName;
        this.fieldType = fieldType.getType();
        this.plasticity = plasticity;
    }


    public Field(int accessModifier, String fieldName, Class fieldType, String plasticity, Object initValue) {
        this.accessModifier = accessModifier;
        this.fieldName = fieldName;
        this.fieldType = SignUtils.class2SignStr(fieldType) + SignUtils.SEMICOLON;
        this.plasticity = plasticity;
        this.initValue = initValue;
    }


    public Field(int accessModifier, String fieldName, ClassType fieldType, String plasticity, Object initValue) {
        this.accessModifier = accessModifier;
        this.fieldName = fieldName;

        //只有主类型 或者混合类型
        if (fieldType.isFix() || fieldType.isOnlyPrimary()) {
            this.fieldType = fieldType.getPrimaryType();
        } else {
            this.fieldType = Type.getType(Object.class).getDescriptor();
        }
        this.plasticity = plasticity;
        this.initValue = initValue;
    }

    public Field(int accessModifier, String fieldName, String fieldType, String plasticity, Object initValue) {
        this.accessModifier = accessModifier;
        this.fieldName = fieldName;
        this.fieldType = fieldType;
        this.plasticity = plasticity;
        this.initValue = initValue;
    }

    public int getAccessModifier() {
        return accessModifier;
    }

    public void setAccessModifier(int accessModifier) {
        this.accessModifier = accessModifier;
    }

    public String getFieldName() {
        return fieldName;
    }

    public void setFieldName(String fieldName) {
        this.fieldName = fieldName;
    }

    public String getFieldType() {
        return fieldType;
    }

    public void setFieldType(String fieldType) {
        this.fieldType = fieldType;
    }

    public String getPlasticity() {
        return plasticity;
    }

    public void setPlasticity(String plasticity) {
        this.plasticity = plasticity;
    }

    public Object getInitValue() {
        return initValue;
    }

    public void setInitValue(Object initValue) {
        this.initValue = initValue;
    }
}
public class Method {


    // public final MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)
    // access:方法访问标识
    // name:方法名称
    // desc:方法描述
    // signature:方法签名,若方法参数、返回类型和异常没有使用泛型则可能为null
    // exceptions:方法的异常名,可能为null

    private int accessModifier = Opcodes.ACC_PUBLIC;
    private String methodName;
    private String argsDesc;
    private String plasticity;
    private String[] exceptions;
    private TypeDesc typeDesc;

    public Method(int accessModifier, String methodName, String argsDesc, String plasticity, String[] exceptions) {
        this.accessModifier = accessModifier;
        this.methodName = methodName;
        this.argsDesc = argsDesc;
        this.plasticity = plasticity;
        this.exceptions = exceptions;
    }


    public Method(int accessModifier, String methodName, TypeDesc typeDesc, String[] exceptions) {
        this.accessModifier = accessModifier;
        this.methodName = methodName;
        this.argsDesc = typeDesc.getDesc().toString();
        this.plasticity = typeDesc.getSign().toString();
        this.exceptions = exceptions;
    }


    public Method(int accessModifier, String methodName, String[] exceptions) {
        this.accessModifier = accessModifier;
        this.methodName = methodName;
        this.argsDesc = argsDesc;
        this.plasticity = plasticity;
        this.exceptions = exceptions;
    }

    public int getAccessModifier() {
        return accessModifier;
    }

    public void setAccessModifier(int accessModifier) {
        this.accessModifier = accessModifier;
    }

    public String getMethodName() {
        return methodName;
    }

    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }

    public String getArgsDesc() {
        return argsDesc;
    }

    public void setArgsDesc(String argsDesc) {
        this.argsDesc = argsDesc;
    }

    public String getPlasticity() {
        return plasticity;
    }

    public void setPlasticity(String plasticity) {
        this.plasticity = plasticity;
    }

    public String[] getExceptions() {
        return exceptions;
    }

    public void setExceptions(String[] exceptions) {
        this.exceptions = exceptions;
    }

    public TypeDesc getTypeDesc() {
        return typeDesc;
    }

    public Method setTypeDesc(TypeDesc typeDesc) {
        this.typeDesc = typeDesc;
        return this;
    }
}
package com.coding.asm.generator;

import java.util.Arrays;

public enum TypeDescriptor {
    BOOL("Z"),
    CHAR("C"),
    BYTE("B"),
    INT("I"),
    FLOAT("F"),
    LONG("J"),
    SHORT("S"),
    DOUBLE("D"),
    VOID("V");

    private String type;

    private TypeDescriptor(String desc) {
        this.type = desc;
    }

    public static TypeDescriptor toEnum(String type) {
        TypeDescriptor[] value = new TypeDescriptor[]{null};
        TypeDescriptor[] values = TypeDescriptor.values();
        Arrays.stream(values).forEach(t -> {
            if (t.getType().equals(type)) {
                value[0] = t;
            }
        });

        return value[0];

    }

    //  Java type Type descriptor
    //  boolean Z
    //  char C
    //  byte B
    //  short S
    //  int I
    //  float F
    //  long J
    //  double D
    //  Object Ljava/lang/Object;
    //  int[] [I
    //  Object[][] [[Ljava/lang/Object;

    public String getType() {
        return this.type;
    }
}
package com.coding.asm.generator;

public class MethodDesc {
    //方法的描述符
    private StringBuilder desc = new StringBuilder();
    //方法签名
    private StringBuilder sign = new StringBuilder();

    public StringBuilder getDesc() {
        return desc;
    }

    public MethodDesc setDesc(StringBuilder desc) {
        this.desc = desc;
        return this;
    }

    public StringBuilder getSign() {
        return sign;
    }

    public MethodDesc setSign(StringBuilder sign) {
        this.sign = sign;
        return this;
    }

}
package com.coding.asm.generator;

import org.objectweb.asm.Type;

/**
 * Created by micocube
 * ProjectName: coding
 * PackageName: com.mico.test.asm
 * User: micocube
 * Email: ldscube@gmail.com
 * CreateTime: 2018/12/27下午2:15
 * ModifyTime: 2018/12/27下午2:15
 * Version: 0.1
 * Description:
 **/
public class ClassType {

    // 主类型的原始class
    private Class primaryOriginalClass;
    // 主类型
    private String primaryType;
    // 范型
    private String[] plasticity;


    // 只有范型
    private Boolean onlyPlasticity = false;
    // 只有主类型
    private Boolean onlyPrimary = false;
    // 混合类型
    private Boolean fix = false;


    // 范型是具体类型
    private Boolean plasticityTypeIsParticular = false;
    // 是否是数组
    private Boolean isArray = false;
    // 是否是原始类型
    private Boolean isPrimitive = false;

    /**
     * 只有主类型,没有范型 eg:java.util.Map
     *
     * @param primaryType
     */
    public ClassType(Class primaryType) {
        this.primaryOriginalClass = primaryType;
        this.onlyPrimary = true;
        String descriptor = getDescriptor(primaryType);
        if (primaryType.isPrimitive()) {
            this.isPrimitive = true;
            this.primaryType = descriptor;
        } else if (primaryType.isArray()) {
            this.isArray = true;
        }
        descriptor = descriptor.endsWith(SignUtils.SEMICOLON) ? descriptor.substring(0, descriptor.length() - 2) : descriptor;
        this.primaryType = descriptor;
    }


    /**
     * 原始类型
     *
     * @param primaryType
     */
    public ClassType(TypeDescriptor primaryType) {
        this.primaryType = primaryType.getType();
        this.onlyPrimary = true;
        this.isPrimitive = true;
    }

    /**
     * 纯范型 比如 T
     *
     * @param plasticity
     */
    public ClassType(String... plasticity) {
        this.plasticity = plasticity;
        this.onlyPlasticity = true;
    }

    /**
     * 混合类型,带范型 eg:java.util.Map<K,V>
     *
     * @param primaryType
     * @param plasticity
     */
    public ClassType(Class primaryType, String... plasticity) {
        this.primaryOriginalClass = primaryType;
        this.plasticity = plasticity;
        this.primaryType = getDescriptor(primaryType);
        this.fix = true;
    }


    /**
     * 混合类型,带具体类型 eg: java.util.Map<String,Object>
     *
     * @param primaryType
     * @param plasticity
     */
    public ClassType(Class primaryType, Class... plasticity) {
        this.primaryOriginalClass = primaryType;
        String[] ps = new String[plasticity.length];
        for (int i = 0; i < plasticity.length; i++) {
            ps[i] = getDescriptor(plasticity[i]);
        }
        this.plasticity = ps;
        this.primaryType = getDescriptor(primaryType);
        this.fix = true;
        this.plasticityTypeIsParticular = true;
    }

    public static ClassType get(Class type) {
        return new ClassType(type);
    }

    public static ClassType get(TypeDescriptor type) {
        return new ClassType(type);
    }

    public static ClassType get(String... plasticity) {
        return new ClassType(plasticity);
    }

    public static ClassType get(Class primaryType, String... plasticity) {
        return new ClassType(primaryType, plasticity);
    }

    public static ClassType get(Class primaryType, Class... plasticity) {
        return new ClassType(primaryType, plasticity);
    }

    private String getDescriptor(Class primaryType) {
        String descriptor = Type.getType(primaryType).getDescriptor();
        descriptor = descriptor.endsWith(SignUtils.SEMICOLON) ? descriptor.substring(0, descriptor.length() - 1) : descriptor;
        return descriptor;
    }


    public Class getPrimaryOriginalClass() {
        return primaryOriginalClass;
    }

    public String getPrimaryType() {
        return primaryType;
    }

    public String[] getPlasticity() {
        return plasticity;
    }

    public Boolean isOnlyPlasticity() {
        return onlyPlasticity;
    }

    public Boolean isOnlyPrimary() {
        return onlyPrimary;
    }

    public Boolean isFix() {
        return fix;
    }

    public Boolean plasticityTypeIsParticular() {
        return plasticityTypeIsParticular;
    }

    public Boolean isArray() {
        return isArray;
    }

    public Boolean isPrimitive() {
        return isPrimitive;
    }
}
package com.coding.asm.generator;

import org.objectweb.asm.Type;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * Created by micocube
 * ProjectName: coding
 * PackageName: com.mico.test.asm
 * User: micocube
 * Email: ldscube@gmail.com
 * CreateTime: 2018/12/27下午4:18
 * ModifyTime: 2018/12/27下午4:18
 * Version: 0.1
 * Description:
 **/
public class SignUtils {


    public static final String CLASS_START = "L";
    public static final String SEMICOLON = ";";
    public static final String COLON = ":";
    public static final String ANGLE_BRACKET_LEFT = "<";
    public static final String ANGLE_BRACKET_RIGHT = ">";
    public static final String DIAGONAL = "/";
    public static final String DOT = ".";
    public static final String PLASTICITY_TYPE = "T";
    public static final String BRACKET_LEFT = "(";
    public static final String BRACKET_RIGHT = ")";


    /**
     * 生成简单的类签名
     * eg: Abc<T, U> extends LinkedHashMap<T, U> implements Iterable<T, U>
     * 签名: <T:Ljava/lang/Object;U:Ljava/lang/Object;>Ljava/util/LinkedHashMap<TT;TU;>;Ljava/lang/Iterable<TT>;
     * 使用方法:
     * String s = utils.genClassSimpleSign(new String[]{"T", "U"},
     * new LinkedHashMap<Class, String[]>() {{
     * put(LinkedHashMap.class, new String[]{"T","U"});
     * }},
     * new LinkedHashMap<Class, String[]>() {{
     * put(Iterable.class, new String[]{"T"});
     * }}
     * );
     *
     * @param classPlasticity
     * @param superClassPlasticity
     * @param interface_plasticity
     * @return
     */

    public static String genClassSimpleSign(
            List<String> classPlasticity,
            ClassType superClassPlasticity,
            List<ClassType> interface_plasticity
    ) {

        StringBuilder sign = new StringBuilder();

        //类范性
        classPlasticity(sign, classPlasticity);

        //超类签名
        superClassPlasticity(sign, superClassPlasticity, classPlasticity);

        //接口签名
        interfacePlasticity(sign, interface_plasticity, classPlasticity);

        return sign.toString();

    }

    //Iterable.class    T,U
    private static void interfacePlasticity(StringBuilder sign, List<ClassType> interface_plasticity, List<String> classPlasticity) {
        interfaceSuperClassPlasticity(sign, interface_plasticity);
    }

    // 超类范型签名
    private static void superClassPlasticity(StringBuilder sign, ClassType superClassPlasticity, List<String> classPlasticity) {
        if (null == superClassPlasticity) {
            sign.append(class2SignStr(Object.class)).append(SEMICOLON);
            return;
        }
        interfaceSuperClassPlasticity(sign, Arrays.asList(superClassPlasticity));
    }

    // 接口范型签名
    private static void interfaceSuperClassPlasticity(StringBuilder sign, List<ClassType> classPlasticity) {
        classPlasticity.forEach((classType) -> {
            String primaryType = classType.getPrimaryType();
            String[] plasticity = classType.getPlasticity();

            if (null == plasticity || plasticity.length == 0) {
                sign.append(primaryType);
            } else {
                sign.append(primaryType).append(ANGLE_BRACKET_LEFT);
                Arrays.stream(plasticity).forEach(ps -> {
                    sign.append(PLASTICITY_TYPE).append(ps).append(SEMICOLON);
                });
                sign.append(ANGLE_BRACKET_RIGHT);
            }
            sign.append(SEMICOLON);
        });
    }

    /**
     * 类范型
     *
     * @param sign
     * @param plasticity
     */
    private static void classPlasticity(StringBuilder sign, List<String> plasticity) {
        if (Objects.nonNull(plasticity) && plasticity.size() != 0) {
            sign.append(ANGLE_BRACKET_LEFT);
            plasticity.stream().forEach(p -> {
                sign.append(p)
                        .append(COLON)
                        .append(class2SignStr(Object.class))
                        .append(SEMICOLON);

            });
            sign.append(ANGLE_BRACKET_RIGHT);
        }

    }

    /**
     * class 转成 类签名
     *
     * @param clazz
     * @return
     */
    public static String class2SignStr(Class<?> clazz) {
        return CLASS_START + class2TypeStr(clazz);
    }


    /**
     * class 转成用/分割的类全路径
     *
     * @param clazz
     * @return
     */
    public static String class2TypeStr(Class<?> clazz) {
        return clazz.getName().replace(DOT, DIAGONAL);
    }


    /**
     * 生成属性签名
     *
     * @param classType
     * @param classPlasticity
     * @return
     */
    public static String genFieldSimpleSign(ClassType classType, List<String> classPlasticity) {
        StringBuilder stringBuilder = new StringBuilder();
        interfacePlasticity(stringBuilder, Arrays.asList(classType), classPlasticity);
        return stringBuilder.toString();
    }


    /**
     * 生成方法签名
     *
     * @param returnType
     * @param argsTypes
     * @param classPlasticity
     * @return
     */
    public static MethodDesc genMethodSign(ClassType returnType, List<ClassType> argsTypes, List<String> classPlasticity) {
        MethodDesc typeDesc = new MethodDesc();
        genMethodArgsTypeSimpleSign(typeDesc, argsTypes, classPlasticity);
        genMethodReturnTypeSimpleSign(typeDesc, returnType, classPlasticity);
        return typeDesc;
    }


    /**
     * 生成返回类型签名
     *
     * @param returnType 返回类型,返回类型范性
     * @return
     */
    private static MethodDesc genMethodReturnTypeSimpleSign(MethodDesc typeDesc, ClassType returnType, List<String> classPlasticity) {

        StringBuilder sign = typeDesc.getSign();
        StringBuilder desc = typeDesc.getDesc();


        String[] plasticity = returnType.getPlasticity();
        String primaryType = returnType.getPrimaryType();
        if (returnType.isOnlyPrimary()) {

            if (null != TypeDescriptor.toEnum(primaryType)) {
                sign
                        .append(primaryType);

                desc
                        .append(primaryType);
            } else {
                sign
                        .append(primaryType)
                        .append(SEMICOLON)
                ;
                desc
                        .append(primaryType)
                        .append(SEMICOLON)
                ;
            }


        } else if (returnType.isOnlyPlasticity()) {
            if (plasticity.length != 1) {
                throw new IllegalArgumentException("只允许一个返回类型!");
            }
            sign.append(PLASTICITY_TYPE)
                    .append(plasticity[0]);

            desc
                    .append(class2SignStr(Object.class));
            desc.append(SEMICOLON);
            sign.append(SEMICOLON);

        } else if (returnType.isFix()) {
            sign.append(primaryType)
                    .append(ANGLE_BRACKET_LEFT);
            desc.append(primaryType);
            genFixTypeSign(sign, desc, returnType, plasticity);

            sign.append(ANGLE_BRACKET_RIGHT);
            desc.append(SEMICOLON);
            sign.append(SEMICOLON);
        }


        return typeDesc;
    }


    /**
     * 生成参数签名
     * (TT;TU;)
     * <p>
     * (ILjava/lang/String;[[Lcom/sosnoski/generics/FileInfo;)V
     * void mmm(int x, String y, FileInfo[][] z)
     *
     * @param types           参数类型,参数类型范型
     * @param classPlasticity
     * @return
     */
    private static MethodDesc genMethodArgsTypeSimpleSign(MethodDesc typeDesc, List<ClassType> types, List<String> classPlasticity) {
        StringBuilder sign = typeDesc.getSign();
        sign.append(BRACKET_LEFT);
        StringBuilder desc = typeDesc.getDesc();
        desc.append(BRACKET_LEFT);
        types.forEach(classType -> {
            String[] plasticity = classType.getPlasticity();
            String primaryType = classType.getPrimaryType();

            if (classType.isOnlyPrimary()) {
                sign
                        .append(primaryType);
                desc
                        .append(primaryType);

                if (!classType.isPrimitive()) {
                    sign.append(SEMICOLON);
                    desc.append(SEMICOLON);
                }

            } else if (classType.isOnlyPlasticity()) {
                Arrays.stream(plasticity).forEach(p -> {
                    sign
                            .append(PLASTICITY_TYPE)
                            .append(p)
                            .append(SEMICOLON);
                    desc.append(Type.getType(Object.class));
                });
            } else if (classType.isFix()) {
                sign.append(primaryType);
                sign.append(ANGLE_BRACKET_LEFT);
                desc.append(primaryType);

                genFixTypeSign(sign, desc, classType, plasticity);

                sign.append(ANGLE_BRACKET_RIGHT);
            }
        });
        sign.append(BRACKET_RIGHT);
        desc.append(BRACKET_RIGHT);
        return typeDesc;
    }


    private static void genFixTypeSign(StringBuilder sign, StringBuilder desc, ClassType classType, String[] plasticity) {
        //具体的范型
        if (classType.plasticityTypeIsParticular()) {
            Arrays.stream(plasticity).forEach(p -> {
                sign
                        .append(p)
                        .append(SEMICOLON);
            });
        } else {
            // T 类型的范型
            Arrays.stream(plasticity).forEach(p -> {
                sign
                        .append(PLASTICITY_TYPE)
                        .append(p)
                        .append(SEMICOLON);
            });
        }
    }

}

package com.coding.asm.generator;

import org.apache.log4j.Logger;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by micocube
 * ProjectName: coding
 * PackageName: com.mico.test.asm
 * User: micocube
 * Email: ldscube@gmail.com
 * CreateTime: 2018/12/20下午4:20
 * ModifyTime: 2018/12/20下午4:20
 * Version: 0.1
 * Description: ASM 工具类
 * https://victorzhzh.iteye.com/category/140253
 * https://blog.csdn.net/Mr__fang/article/details/54846502
 * ASM requires a JDK 1.5 or above.
 * mv = cw.visitMethod(ACC_PUBLIC, "getList","(Ljava/util/Map;)Ljava/util/List;","(Ljava/util/Map<Ljava/lang/String;Ljava/lang/Integer;>;)Ljava/util/List<Ljava/lang/String;>;",null);
 **/
public class AsmUtils {


    private Logger logger = Logger.getLogger(AsmUtils.class);
    private ClassWriter cw;

    public AsmUtils(ClassWriter cw) {
        this.cw = cw;
    }

    public AsmUtils() {
        this.cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    }

    public ClassWriter getCw() {
        return cw;
    }

    /**
     * 写Class 头
     *
     * @param header
     */
    public void writerHeader(Header header) {
        cw.visit(
                header.getVersion(),
                header.getAccessModifier(),
                header.getClassName(),
                header.getPlasticity(),
                header.getSuperClass(),
                header.getInterfaces()
        );
    }

    public void writeClassHeader(
            // 字节码版本
            int version,
            // 类权限修饰符
            int accessModifier,
            // 类名
            String className,
            // 超类
            Class superClass,
            // 接口列表
            List<Class> interfacesClass,
            // 类中所有的范型列表,eg:K,V
            List<String> classPlasticity,
            // 超类范型
            ClassType superClassPlasticity,
            // 接口范型
            List<ClassType> interfacesClassPlasticity
    ) {
        String[] interfaces = null;
        if (null != interfacesClass && interfacesClass.size() != 0) {
            interfaces = new String[interfacesClass.size()];
            for (int i = 0; i < interfacesClass.size(); i++) {
                Class c = interfacesClass.get(i);
                interfaces[i] = SignUtils.class2TypeStr(c);//接口不加L前缀
            }
        }

        String superStr = null;

        if (null != superClass) {
            superStr = SignUtils.class2TypeStr(superClass);//超类不加L前缀
        }

        String sign = SignUtils.genClassSimpleSign(classPlasticity, superClassPlasticity, interfacesClassPlasticity);

        System.out.println("class sign:" + sign);
        Header header = new Header(version,
                accessModifier,
                className,
                sign,
                superStr,
                interfaces);
        writerHeader(header);
    }


    /**
     * 写Field
     *
     * @param field
     */
    public void writeField(Field field) {
        cw.visitField(
                field.getAccessModifier(),
                field.getFieldName(),
                field.getFieldType(),
                field.getPlasticity(),
                field.getInitValue()
        ).visitEnd();
    }


    /**
     * 写field
     *
     * @param accessModifier
     * @param fieldName
     * @param classType
     * @param classPlasticity
     * @param initValule
     */
    public void writeField(int accessModifier, String fieldName, ClassType classType, List<String> classPlasticity, Object initValule) {

        boolean primitiveOrArray = classType.isPrimitive() || classType.isArray() || classType.isOnlyPrimary();
        String sign = primitiveOrArray ? null : SignUtils.genFieldSimpleSign(
                classType,
                classPlasticity);

        String primaryType = classType.getPrimaryType();
        //原始类型不加分号
        if (!classType.isPrimitive()) {
            primaryType = primaryType + SignUtils.SEMICOLON;
        }

        System.out.println("Field Name:" + fieldName + "###Desc:" + primaryType + "####Sign:" + sign);


        // 非final 不要给初始值,没用,即使是final 也要是原始类型,才能反编译后显示初始值
        Field field = new Field(accessModifier, fieldName, primaryType, sign, initValule);
        writeField(field);
    }

    /**
     * 写方法头
     *
     * @param method
     * @return
     */

    public GeneratorAdapter writeMethodHeader(Method method) {
        MethodVisitor methodVisitor = cw.visitMethod(
                method.getAccessModifier(),
                method.getMethodName(),
                method.getArgsDesc(),
                method.getPlasticity(),
                method.getExceptions()
        );
        org.objectweb.asm.commons.Method asmMethod =
                new org.objectweb.asm.commons.Method(method.getMethodName(),
                        method.getTypeDesc().getDesc().toString());

        GeneratorAdapter adapter = new GeneratorAdapter(method.getAccessModifier(),
                asmMethod, methodVisitor);

        return adapter;
    }

    /**
     * 写方法,返回MethodVisitor
     *
     * @param method
     * @return
     */
    public MethodVisitor writeMethod(Method method) {
        return cw.visitMethod(
                method.getAccessModifier(),
                method.getMethodName(),
                method.getArgsDesc(),
                method.getPlasticity(),
                method.getExceptions()
        );
    }


    public void close() {
        cw.visitEnd();
    }

    public byte[] toByteArray() {
        return cw.toByteArray();
    }


    public void writeClass(String path) throws Exception {
        byte[] bytes = toByteArray();
        writeClass(path, bytes);
    }


    public void writeClass(String path, byte[] bytes) throws Exception {
        File file = new File(path);
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(bytes);
        fos.close();
    }


    public Method genMethod(int accessModifier, String methodName, ClassType returnType, List<ClassType> argsTypes, List<String> classPlasticity, String[] exceptions) {
        MethodDesc typeDesc = SignUtils.genMethodSign(returnType, argsTypes, classPlasticity);
        Method method = new Method(accessModifier,
                methodName,
                typeDesc.getDesc().toString(),
                typeDesc.getSign().toString(),
                exceptions);
        method.setTypeDesc(typeDesc);
        System.out.println("Method:" + methodName + "###,Method Sign:" + typeDesc.getSign() + "###,Method desc:" + typeDesc.getDesc());
        return method;
    }


    /**
     * 静态变量入栈
     *
     * @param adapter
     * @param classType
     * @param fieldName
     * @param fieldType
     */
    public void allocateStaticField(GeneratorAdapter adapter, Class classType, String fieldName, Class fieldType) {
        adapter.getStatic(Type.getType(classType), fieldName, Type.getType(fieldType));
    }


    /**
     * 调用静态方法
     *
     * @param adapter
     * @param methodDesc 返回值 方法名 (参数列表) eg: Integer valueOf (int)
     */
    public void allocateStaticMethod(GeneratorAdapter adapter, Class classType, String methodDesc) {
        adapter.invokeStatic(Type.getType(classType), org.objectweb.asm.commons.Method.getMethod(methodDesc));
    }


    /**
     * 调用对象方法
     *
     * @param adapter
     * @param classType
     * @param methodDesc
     */
    public void allocateMethod(GeneratorAdapter adapter, Class classType, String methodDesc) {
        adapter.invokeVirtual(Type.getType(classType), org.objectweb.asm.commons.Method.getMethod(methodDesc));
    }


    /**
     * 调用System.out.println(String)
     *
     * @param adapter
     * @param print
     */
    public void allocatePrintln(GeneratorAdapter adapter, String print) {
        allocateStaticField(adapter, System.class, "out", PrintStream.class);
        adapter.push(print);
        allocateMethod(adapter, PrintStream.class, "void println (String)");
    }


    /**
     * 调用构造方法
     *
     * @param adapter
     */
    public void allocateConstructor(GeneratorAdapter adapter, Class classType) {
        adapter.invokeConstructor(Type.getType(classType), org.objectweb.asm.commons.Method.getMethod("void <init> ()"));
    }


    /**
     * 创建方法域内的局部变量
     *
     * @param adapter
     * @param classType
     */
    public void allocateNewObject(GeneratorAdapter adapter, Class classType) {
        adapter.newInstance(Type.getType(classType));
        adapter.dup();
        allocateConstructor(adapter, classType);
        adapter.visitVarInsn(Opcodes.ASTORE, 1);
        adapter.visitVarInsn(Opcodes.ALOAD, 1);
    }

    /**
     * 方法返回null
     *
     * @param adapter
     */
    public void allocateReturnNull(GeneratorAdapter adapter) {
        adapter.visitInsn(Opcodes.ACONST_NULL);
        adapter.visitMaxs(0, 0);
        returnAndEndMethod(adapter);
    }


    /**
     * 生成默认无参的构造方法,调用超类的构造方法
     *
     * @param adapter
     * @param superClass 超类
     */
    public void genDefaultConstructor(GeneratorAdapter adapter, Class superClass) {
        adapter.loadThis();
        adapter.invokeConstructor(Type.getType(superClass), org.objectweb.asm.commons.Method.getMethod("void <init> ()"));
    }

    /**
     * 生成默认无参的构造方法,调用超类的构造方法
     *
     * @param adapter
     * @param superClass 超类
     */
    public void genDefaultConstructor(GeneratorAdapter adapter, String superClass) {
        adapter.loadThis();
        Type type = Type.getType(superClass);
        logger.debug("<init>: super class:" + type.getDescriptor());
        adapter.invokeConstructor(type, org.objectweb.asm.commons.Method.getMethod("void <init> ()"));
    }

    /**
     * 结束方法
     *
     * @param adapter
     */
    public void returnAndEndMethod(GeneratorAdapter adapter) {
        // 缺少returnValue 将导致
        // 错误: 无法初始化主类 Abc
        //原因: java.lang.VerifyError: Control flow falls through code end
        //Exception Details:
        //  Location:
        //    Abc.main([Ljava/lang/String;)V @8: <invalid>
        //  Reason:
        //    Error exists in the bytecode
        //  Bytecode:
        //    0000000: b200 2212 24b6 002a
        adapter.returnValue();

        //如何让ASM为我计算visitMaxs?
        //调用ClassWriter的构造函数时,请使用COMPUTE_MAXS标志。
        // 您还必须包含visitMaxs方法调用,但忽略您给出的值,因此visitMaxs(0,0)没问题。
        adapter.visitMaxs(0, 0);

        //缺少这句将导致java.lang.VerifyError:
        // (class: Abc, method: main signature: ([Ljava/lang/String;)V) Stack size too large
        adapter.endMethod();
    }


    /**
     * 创建Setter
     *
     * @param className
     * @param fieldType
     * @param fieldName
     * @param classPlasticity
     */
    public void createSetter(String className, ClassType fieldType, String fieldName, List<String> classPlasticity) {
        String methodName = "set" + fieldName.substring(0, 1).toUpperCase()
                + fieldName.substring(1);
//        MethodVisitor mv =
//                cw.visitMethod(Opcodes.ACC_PUBLIC, methodName, "(" + type + ")V", null, null);
//        mv.visitVarInsn(Opcodes.ALOAD, 0);
//        mv.visitVarInsn(Type.getType(c).getOpcode(Opcodes.ILOAD), 1);
//        mv.visitFieldInsn(Opcodes.PUTFIELD, className, propertyName, type);
//        mv.visitInsn(RETURN);
//        mv.visitMaxs(0, 0);
        Method init = genMethod(Opcodes.ACC_PUBLIC, methodName, new ClassType(TypeDescriptor.VOID),
                new ArrayList() {{
                    add(fieldType);
                }}, classPlasticity, null);
        GeneratorAdapter setterAdapter = writeMethodHeader(init);
        setterAdapter.visitVarInsn(Opcodes.ALOAD, 0);
        setterAdapter.visitVarInsn(Type.getType(fieldType.getPrimaryOriginalClass()).getOpcode(Opcodes.ILOAD), 1);
        setterAdapter.putField(Type.getType(className), fieldName, Type.getType(fieldType.getPrimaryOriginalClass()));
        returnAndEndMethod(setterAdapter);
    }

    /**
     * 创建Getter
     *
     * @param className
     * @param fieldType
     * @param fieldName
     * @param classPlasticity
     */
    public void createGetter(String className, ClassType fieldType, String fieldName, List<String> classPlasticity) {
        String methodName = "get" + fieldName.substring(0, 1).toUpperCase()
                + fieldName.substring(1);
//        MethodVisitor mv =
//                cw.visitMethod(Opcodes.ACC_PUBLIC, methodName, "()" + returnType, null, null);
//        mv.visitVarInsn(Opcodes.ALOAD, 0);
//        mv.visitFieldInsn(Opcodes.GETFIELD, internalClassName, propertyName, returnType);
//        mv.visitInsn(Type.getType(c).getOpcode(Opcodes.IRETURN));
//        mv.visitMaxs(0, 0);

        Method init = genMethod(Opcodes.ACC_PUBLIC, methodName, fieldType,
                new ArrayList() {{
                }}, classPlasticity, null);
        GeneratorAdapter getterAdapter = writeMethodHeader(init);
        getterAdapter.visitVarInsn(Opcodes.ALOAD, 0);
        getterAdapter.getField(Type.getType(className), fieldName, Type.getType(fieldType.getPrimaryOriginalClass()));
        returnAndEndMethod(getterAdapter);
    }


}

package com.coding.asm.test;




import com.coding.asm.generator.*;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.GeneratorAdapter;

import java.io.File;
import java.util.*;

/**
 * Created by micocube
 * ProjectName: coding
 * PackageName: com.mico.test.asm
 * User: micocube
 * Email: ldscube@gmail.com
 * CreateTime: 2018/12/20下午4:42
 * ModifyTime: 2018/12/20下午4:42
 * Version: 0.1
 * Description:
 **/
public class Test {
    public static void main(String[] args)throws Exception {
        AsmUtils utils = new AsmUtils();

        List<String> classPlasticity = Arrays.asList("T", "U");

        String className = "Abc";
        utils.writeClassHeader(
                Opcodes.V1_8,
                Opcodes.ACC_PUBLIC,
                className,
                LinkedHashMap.class,
                Arrays.asList(Iterable.class),
                Arrays.asList("K","V"),
                new ClassType(LinkedHashMap.class,"K","V"),
                Arrays.asList(new ClassType(Iterable.class,"K"))
        );





        utils.writeField(Opcodes.ACC_PRIVATE+Opcodes.ACC_STATIC,
                "a",
                ClassType.get(int.class),
                classPlasticity,
                Integer.valueOf(100)
        );


        utils.createGetter(className,ClassType.get(int.class),"a",classPlasticity);
        utils.createSetter(className,ClassType.get(int.class),"a",classPlasticity);

        // 非final 不要给初始值,没用,即使是final 也要是原始类型,才能反编译后显示初始值
        utils.writeField(Opcodes.ACC_PRIVATE+Opcodes.ACC_STATIC+Opcodes.ACC_FINAL,
                "b",
                ClassType.get(TypeDescriptor.DOUBLE),
                classPlasticity,
                Double.valueOf("1000.01")
        );



        utils.writeField(Opcodes.ACC_PRIVATE,
                "c",
                ClassType.get(Map.class,new String[]{"K", "V"}),
                classPlasticity,
                null
        );

        utils.createGetter(className,ClassType.get(Map.class),"c",classPlasticity);
        utils.createSetter(className,ClassType.get(Map.class),"c",classPlasticity);





        Method init = utils.genMethod(Opcodes.ACC_PUBLIC,"<init>",new ClassType(TypeDescriptor.VOID),
                new ArrayList() {{}}, classPlasticity,null);
        GeneratorAdapter initAdapter = utils.writeMethodHeader(init);
        utils.genDefaultConstructor(initAdapter,LinkedHashMap.class);
        utils.returnAndEndMethod(initAdapter);





        // (TT;TU;)V
        Method iterator2 = utils.genMethod(Opcodes.ACC_PUBLIC,"iterator2",new ClassType(Iterator.class),
                new ArrayList() {{
                    add(new ClassType("K"));
                    add(new ClassType("V"));
                }}, classPlasticity,null);
        GeneratorAdapter generatorAdapter = utils.writeMethodHeader(iterator2);
        utils.allocateReturnNull(generatorAdapter);







        Method iterator = utils.genMethod(Opcodes.ACC_PUBLIC,"iterator",new ClassType(Iterator.class,"K"),
                new ArrayList() {{}}, classPlasticity,null);
        GeneratorAdapter iteratorAdapter = utils.writeMethodHeader(iterator);
        utils.allocateReturnNull(iteratorAdapter);








        Method compare = utils.genMethod(Opcodes.ACC_PUBLIC,"compareTo",new ClassType(Integer.class),
                new ArrayList() {{
                    add(new ClassType(Integer.class));
                }}, classPlasticity,null);
        GeneratorAdapter adapter = utils.writeMethodHeader(compare);
        adapter.loadArg(0);
        utils.returnAndEndMethod(adapter);




        Method getA = utils.genMethod(Opcodes.ACC_PUBLIC,"getA",new ClassType("K"),
                new ArrayList() {{add(new ClassType("V"));}}, classPlasticity,null);
        GeneratorAdapter getAdapter = utils.writeMethodHeader(getA);
        utils.allocateReturnNull(getAdapter);






        Method get = utils.genMethod(Opcodes.ACC_PUBLIC,"get",new ClassType(List.class,File.class),
                new ArrayList() {{}}, classPlasticity,null);
        GeneratorAdapter mg = utils.writeMethodHeader(get);
        utils.allocateNewObject(mg,ArrayList.class);
        utils.returnAndEndMethod(mg);





//
        Method main = utils.genMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC,"main",new ClassType(TypeDescriptor.VOID),
                new ArrayList() {{add(new ClassType(String[].class));}}, classPlasticity,null);
        GeneratorAdapter mainAdapter = utils.writeMethodHeader(main);
        utils.allocatePrintln(mainAdapter,"Hello Main!");
        utils.returnAndEndMethod(mainAdapter);






        Method print = utils.genMethod(Opcodes.ACC_PUBLIC ,
                "print",new ClassType(TypeDescriptor.VOID),
                new ArrayList() {{}}, classPlasticity,null);
        GeneratorAdapter printAdapter = utils.writeMethodHeader(print);
        utils.allocatePrintln(printAdapter,"Hello ASM!");
        utils.returnAndEndMethod(printAdapter);








        utils.close();
        utils.writeClass("./target/classes/Abc.class");



    }


}

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class Abc<K, V> extends LinkedHashMap<K, V> implements Iterable<K> {
    private static int a;
    private static final double b = 1000.01D;
    private Map<K, V> c;

    public int getA() {
        return this.a;
    }

    public void setA(int var1) {
        this.a = var1;
    }

    public Map getC() {
        return this.c;
    }

    public void setC(Map var1) {
        this.c = var1;
    }

    public Abc() {
    }

    public Iterator iterator2(K var1, V var2) {
        return null;
    }

    public Iterator<K> iterator() {
        return null;
    }

    public Integer compareTo(Integer var1) {
        return var1;
    }

    public K getA(V var1) {
        return null;
    }

    public List<File> get() {
        ArrayList var1 = new ArrayList();
        return var1;
    }

    public static void main(String[] var0) {
        System.out.println("Hello Main!");
    }

    public void print() {
        System.out.println("Hello ASM!");
    }
}
| => java Abc
# 说明生成成功而且字节码没问题
Hello Main!
package com.coding.asm.test;


import com.coding.asm.generator.*;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.GeneratorAdapter;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by micocube
 * ProjectName: coding
 * PackageName: com.mico.test.asm
 * User: micocube
 * Email: ldscube@gmail.com
 * CreateTime: 2018/12/20下午4:42
 * ModifyTime: 2018/12/20下午4:42
 * Version: 0.1
 * Description:
 **/
public class TestBcd {
    public static void main(String[] args)throws Exception {
        AsmUtils utils = new AsmUtils();


        SignUtils signUtils = new SignUtils();

        List<String> classPlasticity = null;

        utils.writeClassHeader(
                Opcodes.V1_7,
                Opcodes.ACC_PUBLIC,
                "Bcd",
                SignUtils.class,
                Arrays.asList(Comparable.class),
                classPlasticity,
                new ClassType(SignUtils.class),
                Arrays.asList(new ClassType(Comparable.class))
        );





        utils.writeField(Opcodes.ACC_PRIVATE+Opcodes.ACC_STATIC+Opcodes.ACC_FINAL,
                "a",
                ClassType.get(int.class),
                classPlasticity,
                Integer.valueOf(100)
        );








        Method init = utils.genMethod(Opcodes.ACC_PUBLIC,"<init>",new ClassType(TypeDescriptor.VOID),
                new ArrayList() {{}}, classPlasticity,null);
        GeneratorAdapter initAdapter = utils.writeMethodHeader(init);
        utils.genDefaultConstructor(initAdapter,SignUtils.class);
        utils.returnAndEndMethod(initAdapter);


        /**
         *
         public int compareTo(Object o) {
            return 0;
         }
         */
        Method compareTo = utils.genMethod(Opcodes.ACC_PUBLIC,"compareTo",new ClassType(int.class),
                new ArrayList() {{
                    add(new ClassType(Object.class));
                }}, classPlasticity,null);
        GeneratorAdapter compareToAdapter = utils.writeMethodHeader(compareTo);
        compareToAdapter.push(0);
        utils.returnAndEndMethod(compareToAdapter);






//
        Method main = utils.genMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC,"main",new ClassType(TypeDescriptor.VOID),
                new ArrayList() {{add(new ClassType(String[].class));}}, classPlasticity,null);
        GeneratorAdapter mainAdapter = utils.writeMethodHeader(main);
        utils.allocatePrintln(mainAdapter,"Hello Bcd!");
        utils.returnAndEndMethod(mainAdapter);






        Method print = utils.genMethod(Opcodes.ACC_PUBLIC ,
                "print",new ClassType(TypeDescriptor.VOID),
                new ArrayList() {{}}, classPlasticity,null);
        GeneratorAdapter printAdapter = utils.writeMethodHeader(print);
        utils.allocatePrintln(printAdapter,"Hello Print!");
        utils.returnAndEndMethod(printAdapter);








        utils.close();
        utils.writeClass("./target/classes/Bcd.class");



    }


}
package com.coding.asm.test;

import com.coding.asm.generator.SignUtils;

public class Bcd extends SignUtils implements Comparable {
    private static final int a = 100;

    public Bcd() {
    }

    public int compareTo(Object var1) {
        return 0;
    }

    public static void main(String[] var0) {
        System.out.println("Hello BCD!");
    }

    public void print() {
        System.out.println("Hello Print!");
    }
}
# 说明生成成功而且字节码没问题
| => java Bcd
Hello Bcd!
上一篇下一篇

猜你喜欢

热点阅读