• ASM:(3)ClassFile


    原文:https://lsieun.github.io/java-asm-01/asm-vs-classfile.html

    ASM与ClassFile

    我们都知道,在.class文件中,存储的是ByteCode数据。但是,这些ByteCode数据并不是杂乱无章的,而是遵循一定的数据结构。

    image-20220407151807993

    这个.class文件遵循的数据结构就是由Java Virtual Machine Specification中定义的 The class File Format,如下所示。

    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];
    }
    

    字节码类库

    ASM是操作字节码的类库,但并不是唯一的,还有许多其它的操作字节码的类库。

    在下面列举了几个比较常见的字节码类库(按时间先后顺序):

    那么,字节码的类库和ClassFile之间是什么样的关系呢?我们可以用下图来表示:

    image-20220407152849697

    对于上图,我们用三句来描述它们的关系:

    • 中间层-多个.class文件,虽然每个类里面的内容各不相同,但它们里面的内容都称为字节码(ByteCode)。
    • 中下层-不论这些.class文件内容有怎样大的差异,它们都共同遵守同一个数据结构,即ClassFile。
    • 中上层-为了方便于人们对于字节码(ByteCode)内容的操作,逐渐衍生出了各种操作字节码的类库。
    • 上下层-不考虑中间层,我们可以说,不同的字节码类库是在同一个ClassFile结构上发展起来的。

    既然有多个可以选择的字节码类库,那么我们为什么要选择ASM呢?这就得看ASM自身所具有的特点,或者说与众不同的地方。

    ASM的特点

    • 问题:与其它的操作Java字节码的类库相比,ASM有哪些与众不同的地方呢?
    • 回答:在实现相同的功能前提下,使用ASM,运行速度更快(运行时间短,属于“时间维度”),占用的内存空间更小(内存空间,属于“空间维度”)。

    ASM与ClassFile的关系

    为了大家更直观的理解ASM与ClassFile之间关系,我们用下图来表示。其中,Java ClassFile相当于“树根”部分,ObjectWeb ASM相当于“树干”部分,而ASM的各种应用场景属于“树枝”或“树叶”部分

    image-20220407153353979

    学习ASM有三个不同的层次:

    • 第一个层次,ASM的应用层面。也就是说,ASM能够做什么?对于一个.class文件来说,我们可以使用ASM进行analysis、generation和transformation操作。
    • 第二个层次,ASM的源码层面。也就是,ASM的两个组成部分,它为分Core API和Tree API的内容。
    • 第三个层次,Java ClassFile层面。从JVM规范的角度,来理解.class文件的结构,来理解ASM中方法和参数的含义。

    ClassFile快速参考

    对于一个具体的.class而言,它是遵循ClassFile结构的。这个数据结构位于Java Virtual Machine SpecificationThe class File Format部分。

    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];
    }
    

    其中,

    • u1: 表示占用1个字节
    • u2: 表示占用2个字节
    • u4: 表示占用4个字节
    • u8: 表示占用8个字节

    cp_infofield_infomethod_infoattribute_info表示较为复杂的结构,但它们也是由u1u2u4u8组成的。

    相应的,在.class文件当中,定义的字段,要遵循field_info的结构。

    field_info {
        u2             access_flags;
        u2             name_index;
        u2             descriptor_index;
        u2             attributes_count;
        attribute_info attributes[attributes_count];
    }
    

    同样的,在.class文件当中,定义的方法,要遵循method_info的结构。

    method_info {
        u2             access_flags;
        u2             name_index;
        u2             descriptor_index;
        u2             attributes_count;
        attribute_info attributes[attributes_count];
    }
    

    method_info结构中,方法当中方法体的代码,是存在于Code属性结构中,其结构如下:

    Code_attribute {
        u2 attribute_name_index;
        u4 attribute_length;
        u2 max_stack;
        u2 max_locals;
        u4 code_length;
        u1 code[code_length];
        u2 exception_table_length;
        {   u2 start_pc;
            u2 end_pc;
            u2 handler_pc;
            u2 catch_type;
        } exception_table[exception_table_length];
        u2 attributes_count;
        attribute_info attributes[attributes_count];
    }
    
  • 相关阅读:
    nginx一键安装脚本
    nginx动静分离之后,设置默认主页
    日志备份
    cc高防主机部署
    原型和原型链
    Git&Github分支
    Git&Github基础
    传输层协议TCP&UDP
    本地库与远程库交互
    SVG
  • 原文地址:https://www.cnblogs.com/wwjj4811/p/16113410.html
Copyright © 2020-2023  润新知