zoukankan      html  css  js  c++  java
  • jvm(4):类文件结构


    typora-root-url: ./

    类文件结构

    魔数Magic Number

    每个Class文件的头4个字节是魔数。值为0xCAFEBABE

    唯一作用:确定这个文件是一个能被虚拟机接受的Class文件

    Class文件的版本

    紧挨着魔数的4个字节是Class文件的版本号:第5、6个字节是次版本号,第7、8个字节是主版本号

    高版本的JDK能向下兼容以前版本的Class文件,但不能运行以后版本的Class文件。

    常量池

    在常量池的入口处是常量池容量计数值,占两个字节。

    例如,值为0x0016,即22,表示常量池中有21项常量。0表示不引用任何一个常量池项目

    常量池中主要存放两大类常量:字面量符号引用

    常量池中每一项常量都是一个表。表开始的第一位是一个u1类型的标志位,代表当前这个常量属于哪种常量类型。[比如是类或接口,标志位是0x07,类型是CONSTANT_Class_info,即class]

    14种常量类型各自均有自己的结构。[类结构是u1-tag,u2-name_index,值为0x0002,即class #2]

    访问标志

    两个字节,用于识别一些类或者接口层次的访问信息。

    例如,值为0x0200的ACC_INTERFACE标识这是一个接口

    类索引和父类索引

    都是一个u2类型的数据。

    类索引,用于确定这个类的全限定名。指向一个类描述符常量。

    例如,类索引值为0x0001,即const #1

    父类索引,用于确定这个类的父类的全限定名。除了java.lang.Object外,所有Java类的父类索引都不为0。

    接口索引集合

    一组u2类型的数据的集合。

    接口索引集合,用于描述这个类实现了哪些接口。按照implements语句后的接口顺序从左到右排序在接口索引集合中。

    若值为0,则表示没有实现任何接口。否则后面跟着一个索引表。

    字段表集合

    用于描述接口或者类中声明的变量。包括类级变量以及实例级变量。不包括方法内部的局部变量。

    某些信息[比如作用域、可变性、并发可见性等]可以使用标志位。

    某些信息[比如字段名、字段类型]可以引用常量池中的常量来描述。

    类型 名称 数量 含义
    u2 access_flags 1 标志位
    u2 name_index 1 字段的简单名称
    u2 description_index 1 字段和方法的描述符
    u2 attributes_count 1
    attribute_info attributes attributes_count 属性表

    描述符:用一个大写字符表示基本数据类型和void,用L对象的全限定名表示对象类型,用[表示数组类型。

    方法的描述符:按照先参数列表,后返回值的顺序描述。[()V 表示 void inc()]

    例如,access_flags=ACC_PRIVATE,name_index=m,description_index=I,则表示源代码为private int m;

    属性表集合用于存储一些额外的信息。[比如初始化的值]

    字段表不会列出从超类或者父接口中继承而来的字段,但内部类有可能会自动添加指向外部类实例的字段。

    字段无法重载的根本原因是:字段的描述符+字段名不可以重复。

    方法表集合

    和字段表集合差不多。属性表中有一个code属性,存放的是方法里的java代码经过编译器编译的字节码指令。

    方法表不会出现来自父类却没有被override的方法,但有可能出现类构造器<clinit>方法和实例构造器<init>方法。

    方法可以重载:与原方法有同样的简单名称,但是有不同的特征签名[参数列表,不包含返回值]。

    属性表集合

    Code属性

    方法里的java代码经过编译器编译的字节码指令。

    Exceptions属性

    列举方法中可能抛出的受查异常checked exceptions。

    LineBumberTable属性

    描述java源码行号与字节码行号之间的对应关系。

    LocalVariableTable属性

    描述栈帧中局部变量表中的变量与java源码中定义的变量之间的关系。

    SourceFile属性

    用于记录生成这个Class文件的源码文件名称。

    ConstantValue属性

    通知虚拟机自动为静态变量赋值。

    InnerClasses属性

    用于记录内部类与宿主类之间的关联。

    Deprecated及Synthetic属性

    Deprecated用于表示某个类、字段或者方法已经被程序作者定为不再推荐使用。

    Synthetic代表此字段或者方法不是由Java源码直接产生的,而是由编译器自行添加的。

    StackMapTable属性

    变长属性,位于code属性的属性表中。在类加载的字节码验证阶段被新类型检查验证器使用。

    Signature属性

    记录泛型签名信息。

    BootstrapMethods属性

    变长属性,用于保存invokedynamic指令引用的引导方法限定符。

    字节码指令

    JVM采用面向操作数栈的架构,大多数的指令都不包含操作数,只有一个操作码。

    具体可以看jvm指令手册。

    数据类型

    • i:int
    • l:long
    • s:short
    • b:byte
    • c:char
    • f:float
    • d:double
    • a:reference

    加载和存储指令

    局部变量->栈:iload

    操作数栈->局部变量表:istore

    常量->操作数栈:bipush、sipush、ldc、iconst

    扩充局部变量表的访问索引:wide

    运算指令

    类型转换指令

    对象创建与访问指令

    操作数栈管理指令

    控制转移指令

    方法调用和返回指令

    异常处理指令

    同步指令

  • 相关阅读:
    Ext js-02 -官方API文档使用
    [Python3网络爬虫开发实战] 1.1-Python3的安装
    什么是关系型数据库?
    htaccess分布式配置文件常用写法
    PHP无限极分类
    svn在linux上的安装
    优化Web中的性能
    Python 面向对象(初级篇)
    文本日期提取
    HMM分词实例
  • 原文地址:https://www.cnblogs.com/angelica-duhurica/p/11354071.html
Copyright © 2011-2022 走看看