美文网首页
理解Class文件结构

理解Class文件结构

作者: QiShare | 来源:发表于2021-10-19 14:00 被阅读0次

    *.class 是 *.java 编译后的产物,我们来用一个最小的例子看一下class的文件结构

    源代码

    package sample.asm.readclass;
    
    public class Test {
        private String name;
    }
    
    

    反编译

    image image

    class文件结构(The Java Virtual Machine Specification Java SE 7 Edition)

    image

    注意,比如cp_info,cp_info表示常量池,上图中用 constant_pool[constant_pool_count-1]的方式来表示常量池有constant_pool_count-1个常量,它 这里是采用数组的表现形式,但是大家不要误以为所有的常量池的常量长度都是一样的,其实这个地方只是为了方便描述采用了数组的方式,但是这里并不像编程语 言那里,一个int型的数组,每个int长度都一样。

    (1)魔数:CAFEBABE

    (2)minor_version:0000

    (3)major_version:0034

    image

    (4)常量池的数量000F (十进制:15)

    image

    常量池的数量是constant_pool_count-1,为什么减一,是因为索引0表示class中的数据项不引用任何常量池中的常 量。

    (5)常量池

    image image

    每个常量都有一个u1类型的tag标识来表示 常量的类型,第一个常量的类型是0x0A,转换成二级制是10,有上面的关于常量类型的描述可知tag为10的常量是Constant_Methodref_info


    image
    tag class_index name_and_type_index
    0A 0003 000C
    --- #3(#14 java/lang/Object) #12(#6#7 <init>()V)

    (6)u2 access_flags 0021

    image

    表示类或者接口方面的访问信息,比如Class表示的是类还是接口,是否为public,static,final等。0x0021=0x0001|0x0020 也即ACC_PUBLIC 和 ACC_SUPER为真,其中ACC_PUBLIC大家好理解,ACC
    _SUPER是jdk1.2之后编译的类都会带有的标志。

    (7)u2 this_class 0002

    image

    表示类的索引值,用来表示类的全限定名称 sample/asm/readclass/Test

    (8)u2 super_class:0003

    image

    表示当前类的父类的索引值 java/lang/Object

    (9)interfaces_count和 interfaces[interfaces_count]表示接口数量以及具体的每一个接口

    image

    (10)fields_count 和 field_info

    image
    image

    fields_count:1 (0001)

    field_info:0002 0004 0005 0000

    access_flag name_index descriptor_index attribute_count
    0002 0004 0005 0000
    --- name Ljava/lang/String; 0

    (11)methods_count 和 method_info:

    image
    image image
    access_flag name_index descriptor_index attribute_count attribute_info
    0001 0006 0007 0001 ---
    --- <init> ()V 1 ---

    接下来是attribute_info
    0008对应的常量池中的常量为Code,表示的方法的Code属性,所以到这里大家应该明白方法的那些代码是存储在Class文件方法表中的属性表中的Code属性中。接下来我们在分析一下Code属性,Code属性的结构如下


    class-15
    attribute_name_index attribute_length max_stack max_locals code_length code[code_length]
    0008 0000001D 0001 0001 00000005 2AB70001B1
    exception_table_length attribute_count attribute_info
    0000 0001 ---
    image

    0009,它表示常量池中属性的名称,查看常量池得知第9个常量的值为 LineNumberTable,LineNumberTable用于描述java源代码的行号和字节码行号的对应关系,它不是运行时必需的属性,如果通 过-g:none的编译器参数来取消生成这项信息的话,最大的影响就是异常发生的时候,堆栈中不能显示出出错的行号,调试的时候也不能按照源代码来设置断点,接下来我们再看一下LineNumberTable的结构如下图所示:


    image
    attribute_name_index attribute_length 字节流
    0009 00000006 0001(有1个行号表) 0000(字节码行号0) 0003(源码行号3)
    image

    Class文件的属性

    属性数量:0001

    attribute_name_index attribute_length sourcefile_index
    000A 00000002 000B
    SourceFile 00000002 Test.java
    image

    相关文章

      网友评论

          本文标题:理解Class文件结构

          本文链接:https://www.haomeiwen.com/subject/zcdaoltx.html