美文网首页
JVM Class文件结构

JVM Class文件结构

作者: Van96 | 来源:发表于2017-05-07 20:09 被阅读63次

    在class文件中,有两种数据类型:无符号数和表,其他的都是数据了
    无符号数:以u1、u2、u4、u8来分别代表1个字节、2个字节、4个字节和8个字节的无符号数;
    表:相当于C中的结构体,表中可以含有若干个无符号数以及子表,表类型名一般用info为结尾,事实上,Class文件整体也是一个表(以下为Class文件的数据项构成):

    Class文件的数据项构成

    【1】常量池中只要存放两大类常量:字面量(Literal)和符号引用(Symbolic References),字面量比较接近于Java语言层面上的常量概念,如文本字符串,声明为final的常量值等。而符号引用则属于编译层面的概念,包含以下三类常量:

    • 类和接口的全限定名(Fully Qualified Name)
    • 字段的名称和描述符(Descriptor)
    • 方法的名称和描述符

    【2】标识这个Class是否为(class、接口、枚举、注解),是否为public,是否为(final、abstract)

    【3】类索引,父类索引和接口索引确定了这个类的继承关系。类索引和父类索引都上一个索引,通过这个索引,我们可以在常量池中找到需要的类全限定名。
    (具体的做法是:这个两个类索引会指向一个类型为CONSTANT_Class_info的类描述符常量,通过这个常量,可以找到定义在CONSTANT_Utf8_info类型中的全限定名字符串)

    【4】在这个表中,需要描述字段的作用域(public、private等修饰符),是否为类变量(static),可变性(fianl),并发可见性(volatile),可否被序列化(transient)(以上为字段修饰符)
    字段数据类型(基本数据类型,对象,数组),字段名称。
    具体情况:

    字段表

    【4.1】描述符的作用是,用来描述字段的数据类型,方法的参数列表和返回值。每个基本数据类型(int、float等)和void类型都会使用一个大写字母表示:

    参照表

    而对象类型用字符L加对象的全限定名来表示
    另外,对于数组类型而言,每一维用一个[来表示。对于方法而言,会将参数列表中的参数的描述符依次放到一对括号中,在括号的后面再接上这个方法返回值的描述符,举几个栗子:
    一个char类型的变量, 描述符为C
    一个二维String数组 String[][] arr, 描述符为“[[Ljava/lang/String”
    一个方法 String func(int p,char[] k,char t) 描述符为:“(I[CC)Ljava/lang/String”

    在字节码中,如果两个字段的描述符不一致,那么重名也是合法的。

    【4.2】字段表的属性表
    字段表中的属性项会描述以下几个属性:

    • ConstantValue,final关键字定义的关键字
    • Deprecated,被声明为deprecaated的字段

    【5】方法表与字段表基本一致(因此就不重复列出方法表的结构了),与之有一点细微差别的就是access_flags,对于一个方法,需要的描述的修饰符为:可见性修饰符(public、private等),静态修饰符(static),可否被重写(final,abstract),是否为同步方法(synchronized),是否为本地方法(native),是否需要严格浮点运算(stricfp)
    此外还有就是:方法是否接受不定参数,是否为编译器产生的桥接方法,是否由编译器自动产生;
    方法表的属性表见【5.1】

    【5.1】方法表的属性表
    常用的有以下的几个属性:

    • Code,代码编译成的字节码指令(同样也是一个表)
    • Deprecated,被声明为deprecaated的方法
    • Exceptions,方法抛出的异常

    【6】类文件的属性表

    • EnclosingMethod,仅当一个类为局部类或匿名类时才能拥有这个属性,这个属性用于标识这个类所在的外围方法
    • innerClasses,内部类列表

    相关文章

      网友评论

          本文标题:JVM Class文件结构

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