Java虚拟机:class类文件结构

Java虚拟机:class类文件结构

一、平台无关性:

        Java的无关性的实现,是由Java源代码编译后生成的字节码class文件和Java虚拟机实现的。无关性包括:平台无关性以及语言无关性。

    (1)平台无关性,是指java代码可以运行在不同操作系统的虚拟机上面,因为不同的操作系统都有各自的Java虚拟机,从而实现程序的“一次编写,到处运行”。

    (2)语言无关性是指Java虚拟机能运行除Java以外的代码,JVM执行的是class文件,也就是JVM只认识class文件,它并不关心Class文件的来源是什么语言,只要它符合一定的结构,就可以在Java中运行。

 

二、类文件结构:

class文件是Java虚拟机执行引擎的数据入口,是一组以8位字节为基础单位的二进制流,存储的内容几乎都是程序运行的必要数据。

class文件的数据存储结构中只有两种数据类型:无符号数和表。class文件中的数据项,都被严格限定的,每个字节代表的含义,长度,先后顺序等都不允许改变。

(1)无符号数属于基本数据类型,以u1、u2、u4、u8来分别代表1、2、4、8个字节的无符号数。

(2)表是由多个无符号数或其他表作为数据项构成的复合数据类型。

class类文件的结构:

    1. 魔数

    2. 文件版本信息

    3. 常量池

    4. 访问标志

    5. 类索引、父类索引、接口索引集合

    6. 字段表集合

    7. 方法表集合

    8. 属性表集合

1、魔数:

        每个Class文件的头4个字节称为魔数(magic),它的唯一作用是判断该文件是否为一个能被虚拟机接受的Class文件。它的值固定为0xCAFEBABE。

2、文件版本信息:

        紧接着magic的4个字节存储的是Class文件的次版本号和主版本号,高版本的JDK能向下兼容低版本的Class文件,但不能运行更高版本的Class文件,即使该版本没有用到高版本JDK的特性。

3、常量池:

        紧接着版本号之后的就是常量池入口,它是class文件中的资源仓库。它是Class文件中与其他项目关联最多的数据类型,也是占用Class文件空间最大的数据项目之一。常量池中主要存放两大类常量:字面量和符号引用。

        字面量比较接近于Java层面的常量概念,如文本字符串、被声明为final的常量值等。

        而符号引用总结起来则包括了下面三类常量:

         (1)类和接口的全限定名

         (2)字段的名称和描述符

         (3)方法的名称和描述符

4、访问标志:

        在常量池结束之后,紧接着的2个字节代表访问标志(access_flag),这个标志用于识别一些类或接口层次的访问信息,包括:这个Class是类还是接口,是否定义为public类型,abstract类型,如果是类的话,是否声明为final,等。

5、类索引、父类索引、接口索引集合:

        Class文件中由这三项数据来确定这个类的继承关系。类索引、父类索引和接口索引集合都按照顺序排列在访问标志之后。类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名。接口索引集合就用来描述这个类实现了哪些接口。

6、字段表集合:

        字段表(field_info)用于描述接口或类中声明的变量。字段包括了类级变量或实例级变量,但不包括在方法内声明的变量。可以包括的信息有:字段的作用域、是实例变量还是类变量、可变性、并发可见性、可否被序列化、字段数据类型、字段名称。但是,字段的名字、数据类型、修饰符等都是无法固定的,只能引用常量池中的常量来描述。

        字段表集合中不会列出从父类或接口中继承而来的字段,但有可能列出原本Java代码中不存在的字段。比如在内部类中为了保持对外部类的访问性,会自动添加指向外部类实例的字段。

7、方法表集合:

        方法表(method_info)的结构与字段表的结构相同。方法里的Java代码,经过编译器编译成字节码指令后,存放在方法属性表集合中一个名为“Code”的属性里。

        与字段表集合相对应,如果父类方法在子类中没有被覆写,方法表集合中就不会出现来自父类的方法信息。但同样,有可能会出现由编译器自动添加的方法,最典型的便是类构造器“<clinit>”方法和实例构造器“<init>”方法。

        重载一个方法需要有相同的简单名称和不同的特征签名。JVM的特征签名和Java的特征签名有所不同: 

        (1)Java特征签名:方法参数在常量池中的字段符号引用的集合

        (2)JVM特征签名:方法参数+返回值

8、属性表集合:

        属性表(attribute_info),在Class文件、字段表、方法表中都可以携带自己的属性表集合,以用于描述某些场景专有的信息。

(1)Code属性:

        Java程序方法体中的代码讲过Javac编译后,生成的字节码指令便会存储在Code属性中,但并非所有的方法表都必须存在这个属性,比如接口或抽象类中的方法就不存在Code属性。

        Code属性是Class文件中最重要的一个属性,如果把一个Java程序中的信息分为代码和元数据两部分,那么在整个Class文件里,Code属性用于描述代码,所有的其他数据项目都用于描述元数据。

(2)Exception属性:

        这里的Exception属性的作用是列举出方法中可能抛出的受查异常,也就是方法描述时在throws关键字后面列举的异常。

(3)LineNumberTable属性:

        它用于描述Java源码行号与字节码行号之间的对应关系。

(4)LocalVariableTable属性:

        它用于描述栈帧中局部变量表中的变量与Java源码中定义的变量之间的对应关系。

(5)SourceFile属性:

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

(6)ConstantValue属性:

        ConstantValue属性的作用是通知虚拟机自动为静态变量赋值,只有被static修饰的变量才可以使用这项属性。

        在Java中,对非static类型的变量(也就是实例变量)的赋值是在实例构造器<init>方法中进行的;而对于类变量(static变量),则有两种方式可以选择:在类构造其中赋值,或使用ConstantValue属性赋值。

        如果同时使用final和static修饰一个变量(即全局常量),并且这个变量的数据类型是基本类型或String的话,就生成ConstantValue属性来进行初始化,如果该变量没有被final修饰,或者并非基本类型及字符串,则选择在<clinit>方法中进行初始化。

(7)InnerClasses属性:

        该属性用于记录内部类与宿主类之间的关联。如果一个类中定义了内部类,那么编译器将会为它及它所包含的内部类生成InnerClasses属性。

(8)Deprecated属性:

        Deprecated该属性用于表示某个类、字段和方法,已经被程序作者定为不再推荐使用,它可以通过在代码中使用@Deprecated注释进行设置。

(9)Synthetic属性:

        该属性代表此字段或方法并不是Java源代码直接生成的,而是由编译器自行添加的,如this字段和实例构造器、类构造器等。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/114741.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Oracle数据块原理深入剖析

    Oracle数据块原理深入剖析

    2021年8月30日
    53
  • MVC框架模式与SpringMVC框架

    MVC框架模式与SpringMVC框架1 框架与设计模式框架 设计模式这两个概念很容易被人混淆 但其实这两者之间还是存在差别的 框架通常是代码重用 而设计模式是设计重用 nbsp 设计模式是对反复出现的问题的解决方案的描述 是一种思想用于处理细节的 比框架更加抽象 框架是已经用代码实现的 可以执行也可以复用 设计模式是比框架更小的元素 一个框架往往会包含一个或者多个设计模式 框架总是针对某一特定领域的 而设计模式则可以适用于各个

    2025年9月13日
    6
  • mac版idea2021.5激活码[在线序列号]

    mac版idea2021.5激活码[在线序列号],https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月18日
    47
  • Java面试宝典(2019版)

    Java面试宝典(2019版)附Java/C/C++/机器学习/算法与数据结构/前端/安卓/Python/程序员必读书籍书单大全:书单导航页(点击右侧极客侠栈即可打开个人博客):极客侠栈①【Java】学习之路吐血整理技术书从入门到进阶最全50+本(珍藏版)②【算法数据结构+acm】从入门到进阶吐血整理书单50+本(珍藏版)③【数据库】从入门到进阶必读18本技术书籍网盘吐血整理网盘(珍藏版)④【Web前端】从HT…

    2022年7月14日
    16
  • Android 六大布局之 GridLayout(网格布局)「建议收藏」

    Android 六大布局之 GridLayout(网格布局)「建议收藏」目录GridLayout(网格布局)简述计算器布局的实现GridLayout(网格布局)简述GridLayout布局是Android4.0以后引入的新布局,和TableLayout(表格布局)有点类似,不过它功能更多,也更加好用可以自己设置布局中组件的排列方式 可以自定义网格布局有多少行,多少列 可以直接设置组件位于某行某列 可以设置组件横跨几行或者几列…

    2022年5月7日
    68
  • 关于Delay函数的思考

    关于Delay函数的思考可能很多人对延时函数的使用并不排斥,但是我个人觉得这是非常不符合软件的本质的。软件的本质是将现实中的各种行为抽象。以现实中人的活动为例,人在同一时刻是可以实时响应很多事情的,而Delay函数的出现相当于给CPU上了刹车

    2022年5月5日
    40

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号