0

0

java虚拟机之class文件结构介绍

零下一度

零下一度

发布时间:2017-06-25 10:41:04

|

1870人浏览过

|

来源于php中文网

原创

一、前言

学习java的朋友应该都知道java从刚开始的时候就打着平台无关性的旗号,说“一次编写,到处运行”,其实说到无关性,java平台还有另外一个无关性那就是语言无关性,要实现语言无关性,那么java体系中的class的文件结构或者说是字节码就显得相当重要了,其实java从刚开始的时候就有两套规范,一个是java语言规范,另外一个是java虚拟机规范,java语言规范只是规定了java语言相关的约束以及规则,而虚拟机规范则才是真正从跨平台的角度去设计的

或许大部分程序员都认为Java虚拟机执行Java程序是一件理所当然和天经地义的事,但时至今日,商业机构和开源机构已经在Java语言之外发展出一大批在Java虚拟机之上运行的语言,如Clojure、Groovy、JRuby、Jython、Scale等。使用Java编译器可以把Java代码编译为存储字节码的Class文件,使用JRuby等其它语言的编译器一样可以把程序代码编译成Class文件,Java之所以能够跨平台运行,是因为Java虚拟机可以载入和执行同一种平台无关的字节码。也就是说,实现语言平台无关性的基础是虚拟机和字节码存储格式,虚拟机并不关心Class的来源是什么语言,只要它符合Class文件应有的结构就可以在Java虚拟机中运行。

二、Class文件编码与组成

1)Class文件是由byte(8bit)为基础的字节流构成的,这些字节流之间都严格按照规定的顺序排列,并且字节之间不存在任何空隙,对于超过8个字节的数据,将按照Big-Endian的顺序存储的,也就是说高位字节存储在低的地址上面,而低位字节存储到高地址上面,其实这也是class文件要跨平台的关键,因为PowerPC架构的处理采用Big-Endian的存储顺序,而x86系列的处理器则采用Little-Endian的存储顺序,因此为了Class文件在各中处理器架构下保持统一的存储顺序,虚拟机规范必须对其进行统一。

2) Class文件结构采用类似C语言的结构体来存储数据的,主要有两类数据项,无符号数和表,无符号数用来表述数字,索引引用以及字符串等,比如 u1,u2,u4,u8分别代表1个字节,2个字节,4个字节,8个字节的无符号数,而表是有多个无符号数以及其它的表组成的复合结构。可能大家看到这里 对无符号数和表到底是上面也不是很清楚,不过不要紧,等下面实例的时候,我会再以实例来解释。
明确了上面的两点以后,我们接下来后来看看Class文件中按照严格的顺序排列的字节流都具体包含些什么数据:

立即学习Java免费学习笔记(深入)”;

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

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

久久企业网站后台管理系统1.0
久久企业网站后台管理系统1.0

一、功能简介本软件完全适应大、中、小型网站建设需要,让您用很便宜的虚拟主机空间也可以开通4个独立的网站!久久企业网站后台管理系统各种版本开发基础架构均为php+mysql+div+css+伪静态,迎合搜索引擎排名的喜好。另外值得一提的是本站特色的TAG系统可为您的网站做出无限分类,不用任何设置全站ULR伪静态!本建站系统除了有产品发布、新闻(软文)发布、订单管理系统和留言反馈等一些最基本的功能之外

下载

三、Class文件结构各部分具体介绍

1)u4 magic 表示魔数,并且魔数占用了4个字节,魔数到底是做什么的呢?它其实就是表示一下这个文件的类型是一个Class文件,而不是一张JPG图片,或者AVI的电影。而Class文件对应的魔数是0xCAFEBABE.
2)u2 minor_version 表示Class文件的次版本号,并且此版本号是u2类型的无符号数表示。
3)u2 major_version 表示Class文件的主版本号,并且主版本号是u2类型的无符号数表示。major_version和minor_version主要用来表示当前的虚拟机是否接受当前这种版本的Class文件。不同版本的Java编译器编译的Class文件对应的版本是不一样的。高版本的虚拟机支持低版本的编译器编译的Class文件结构。比如Java SE 6.0对应的虚拟机支持Java SE 5.0的编译器编译的Class文件结构,反之则不行
4)u2 constant_pool_count 表示常量池的数量。这里我们需要重点来说一下常量池是什么东西,请大家不要与Jvm内存模型中的运行时常量池混淆了,Class文件中常量池主要存储了字面量以及符号引用,其中字面量主要包括字符串,final常量的值或者某个属性的初始值等等,而符号引用主要存储类和接口的全限定名称,字段的名称以及描述符,方法的名称以及描述符,这里名称可能大家都容易理解,至于描述符的概念,放到下面说字段表以及方法表的时候再说。另外大家都知道Jvm的内存模型中 有堆,栈,方法区,程序计数器构成,而方法区中又存在一块区域叫运行时常量池,运行时常量池中存放的东西其实也就是编译器产生的各种字面量以及符号引用, 只不过运行时常量池具有动态性,它可以在运行的时候向其中增加其它的常量进去,最具代表性的就是String的intern方法
5)cp_info 表示常量池,这里面就存在了上面说的各种各样的字面量和符号引用。放到常量池的中数据项一共有14个常量,每一种常量都是一个表,并且每种常量都用一个公共的部分tag来表示是哪种类型的常量。

Constant Type Value
CONSTANT_Class 7
CONSTANT_Fieldref 9
CONSTANT_Methodref 10
CONSTANT_InterfaceMethodref 11
CONSTANT_String 8
CONSTANT_Integer 3
CONSTANT_Float 4
CONSTANT_Long 5
CONSTANT_Double 6
CONSTANT_NameAndType 12
CONSTANT_Utf8 1
CONSTANT_MethodHandle 15
CONSTANT_MethodType 16
CONSTANT_InvokeDynamic 18


6)u2 access_flags 表示类或者接口的访问信息,具体如下图所示:

Flag Name Value Interpretation
ACC_PUBLIC 0x0001 Declared public; may be accessed from outside its package.
ACC_FINAL 0x0010 Declared final; no subclasses allowed.
ACC_SUPER 0x0020 Treat superclass methods specially when invoked by the invokespecial instruction.
ACC_INTERFACE 0x0200 Is an interface, not a class.
ACC_ABSTRACT 0x0400 Declared abstract; must not be instantiated.
ACC_SYNTHETIC 0x1000 Declared synthetic; not present in the source code.
ACC_ANNOTATION 0x2000 Declared as an annotation type.
ACC_ENUM 0x4000 Declared as an enum type.

7)u2 this_class 表示类的常量池索引,指向常量池中CONSTANT_Class的常量
8)u2 super_class 表示超类的索引,指向常量池中CONSTANT_Class的常量
9)u2 interface_counts 表示接口的数量
10)u2 interface[interface_counts]表示接口表,它里面每一项都指向常量池中CONSTANT_Class常量
11)u2 fields_count 表示类的实例变量和类变量的数量
12) field_info fields[fields_count]表示字段表的信息,其中字段表的结构如下图所示:

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

上图中access_flags表示字段的访问表示,比如字段是public、private、protect 等,name_index表示字段名称,指向常量池中类型是CONSTANT_UTF8的常量,descriptor_index表示字段的描述符,它也指向常量池中类型为 CONSTANT_UTF8的常量,attributes_count表示字段表中的属性表的数量,而属性表是则是一种用与描述字段,方法以及 类的属性的可扩展的结构,不同版本的Java虚拟机所支持的属性表的数量是不同的。
13) u2 methods_count表示方法表的数量
14)method_info 表示方法表,方法表的具体结构如下图所示:

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

其中access_flags表示方法的访问表示,name_index表示名称的索引,descriptor_index表示方法的描述符,attributes_count以及attribute_info类似字段表中的属性表,只不过字段表和方法表中属性表中的属性是不同的,比如方法表中就有Code属性,表示方法的代码,而字段表中就没有Code属性。
15) attribute_count表示属性表的数量,说到属性表,我们需要明确以下几点:
属性表存在于Class文件结构的最后,字段表,方法表以及Code属性中,也就是说属性表中也可以存在属性表,属性表的长度是不固定的,不同的属性,属性表的长度是不同的

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

0

2026.01.21

windows激活码分享 windows一键激活教程指南
windows激活码分享 windows一键激活教程指南

Windows 10/11一键激活可以通过PowerShell脚本或KMS工具实现永久或长期激活。最推荐的简便方法是打开PowerShell(管理员),运行 irm https://get.activated.win | iex 脚本,按提示选择数字激活(选项1)。其他方法包括使用HEU KMS Activator工具进行智能激活。

0

2026.01.21

excel表格操作技巧大全 表格制作excel教程
excel表格操作技巧大全 表格制作excel教程

Excel表格操作的核心技巧在于 熟练使用快捷键、数据处理函数及视图工具,如Ctrl+C/V(复制粘贴)、Alt+=(自动求和)、条件格式、数据验证及数据透视表。掌握这些可大幅提升数据分析与办公效率,实现快速录入、查找、筛选和汇总。

1

2026.01.21

毒蘑菇显卡测试网站入口 毒蘑菇测试官网volumeshader_bm
毒蘑菇显卡测试网站入口 毒蘑菇测试官网volumeshader_bm

毒蘑菇VOLUMESHADER_BM测试网站网址为https://toolwa.com/vsbm/,该平台基于WebGL技术通过渲染高复杂度三维分形图形评估设备图形处理能力,用户可通过拖动彩色物体观察画面流畅度判断GPU与CPU协同性能;测试兼容多种设备,但中低端手机易卡顿或崩溃,高端机型可能因发热降频影响表现,桌面端需启用独立显卡并使用支持WebGL的主流浏览器以确保准确结果

2

2026.01.21

github中文官网入口 github中文版官网网页进入
github中文官网入口 github中文版官网网页进入

github中文官网入口https://docs.github.com/zh/get-started,GitHub 是一种基于云的平台,可在其中存储、共享并与他人一起编写代码。 通过将代码存储在GitHub 上的“存储库”中,你可以: “展示或共享”你的工作。 持续“跟踪和管理”对代码的更改。

2

2026.01.21

windows安全中心怎么关闭打开_windows安全中心操作指南
windows安全中心怎么关闭打开_windows安全中心操作指南

Windows安全中心可以通过系统设置轻松开关。 暂时关闭:打开“设置” -> “隐私和安全性” -> “Windows安全中心” -> “病毒和威胁防护” -> “管理设置”,将“实时保护”关闭。打开:同样路径将开关开启即可。如需彻底关闭,需在组策略(gpedit.msc)或注册表中禁用Windows Defender。

1

2026.01.21

C++游戏开发Unreal Engine_C++怎么用Unreal Engine开发游戏
C++游戏开发Unreal Engine_C++怎么用Unreal Engine开发游戏

虚幻引擎(Unreal Engine, 简称UE)是由Epic Games开发的一款功能强大的工业级3D游戏引擎,以高品质实时渲染(如Nanite和Lumen)闻名 。它基于C++语言,为开发者提供高效率的框架、强大的可视化脚本系统(蓝图)、以及针对PC、主机和移动端的完整开发工具,广泛用于游戏、电影制片等领域。

0

2026.01.21

Python GraphQL API 开发实战
Python GraphQL API 开发实战

本专题系统讲解 Python 在 GraphQL API 开发中的实际应用,涵盖 GraphQL 基础概念、Schema 设计、Query 与 Mutation 实现、权限控制、分页与性能优化,以及与现有 REST 服务和数据库的整合方式。通过完整示例,帮助学习者掌握 使用 Python 构建高扩展性、前后端协作友好的 GraphQL 接口服务,适用于中大型应用与复杂数据查询场景。

1

2026.01.21

云朵浏览器入口合集
云朵浏览器入口合集

本专题整合了云朵浏览器入口合集,阅读专题下面的文章了解更多详细地址。

22

2026.01.20

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
前端系列快速入门课程
前端系列快速入门课程

共4课时 | 0.4万人学习

react hooks实战移动端企业级项目
react hooks实战移动端企业级项目

共59课时 | 6.4万人学习

Kotlin 教程
Kotlin 教程

共23课时 | 2.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号