• ASM之ClassWriter


    ASM之ClassWriter

    ClassWriter的父类是ClassVistor,它可以在编辑完字节码后通过toByteArray()方法将所有的visit做的操作转换为byte[],而这些byte[]的内容就遵循classFile的结构,所以将其通过FileOutputStream写入文件后就是可执行的class文件

    先说ClassWriter的结构

    这是classWriter定义的字段

    public class ClassWriter extends ClassVisitor {
        private int version;
        private final SymbolTable symbolTable;
    
        private int accessFlags;
        private int thisClass;
        private int superClass;
        private int interfaceCount;
        private int[] interfaces;
    
        private FieldWriter firstField;
        private FieldWriter lastField;
    
        private MethodWriter firstMethod;
        private MethodWriter lastMethod;
    
        private Attribute firstAttribute;
    
        //......
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    可以发现上面的字段和classFile的结构一样

    ClassFile {
        u4             magic;
        u2             minor_version;
        u2             major_version;
        u2             constant_pool_count;
        cp_info        constant_pool[constant_pool_count-1];
        u2             access_flags;
        u2             this_class;
        u2             super_class;
        u2             interfaces_count;
        u2             interfaces[interfaces_count];
        u2             fields_count;
        field_info     fields[fields_count];
        u2             methods_count;
        method_info    methods[methods_count];
        u2             attributes_count;
        attribute_info attributes[attributes_count];
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    然后我们看看ClassWriter的构造方法

    这里推荐使用flags使用COMPUTE_FRAMES ,这个flags作用如下图,主要作用在classFile结构的方法表里面

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    在创建ClassWriter对象时,我们可以传入的flags可选值有三个

    • 0:ASM不会自动计算max stacks、max locals、stack map frames
    • COMPUTE_MAXS:ASM会自动计算max stacks、max locals,但不会计算stack map frames,这样开发效率是比较高的
    • COMPUTE_FRAMES:ASM会自动计算max stacks、max locals、stack map frames,这样开发效率比较低下,但是不需要我们手动计算出以上的这些值
    public class ClassWriter extends ClassVisitor {
        /* A flag to automatically compute the maximum stack size and the maximum number of local variables of methods. */
        public static final int COMPUTE_MAXS = 1;
        /* A flag to automatically compute the stack map frames of methods from scratch. */
        public static final int COMPUTE_FRAMES = 2;
    
        // flags option can be used to modify the default behavior of this class.
        // Must be zero or more of COMPUTE_MAXS and COMPUTE_FRAMES.
        public ClassWriter(final int flags) {
            this(null, flags);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    中间会被调用的visit方法请查看

    ASM之ClassVistor

    最后我们需要生成class的字节码时会调用toByteArray()方法,这个方法通过三个步骤最终获得byte[]

    1. 计算size大小
    2. 将数据填充到byte[]
    3. 将byte[]返回
  • 相关阅读:
    切分支解决切不走因为未合并的路径如何解决
    react 中获取多个input输入框中的值的 俩种写法
    pytorch深度学习实战lesson5
    LeetCode42:接雨水
    java.lang.Float类下hashCode()方法具有什么功能呢?
    APP定制开发流程和特点有哪些?
    Spring Cloud Alibaba(四)
    不能乱动的依赖包glibc,openssl,libcom_err
    stream流参数总结
    论文阅读之Multimodal Chain-of-Thought Reasoning in Language Models
  • 原文地址:https://blog.csdn.net/WitheredSkull/article/details/134555337