Class文件是一组以8位字节为基础单位的二进制流,各数据项严格按顺序排列其中,中间没有添加任何分隔符.
根据JAVA虚拟机规范的规定,CLASS文件格式采用一种类似C语言结构体的伪结构来存储,这种伪结构中只有两种数据类型:无符号数和表。
无符号数属于基本的数据类型,以u1,u2,u4,u8来分别表示一个字节,两个字节,四个字节和8个字节的无符号数,无符号数用来描述数字,索引引用,数量值或按照UTF8编码构成字符串数
表是由多个无符号数或其他表作为数据项构成的复合数据类型,所有表都习惯性的以"_info"结尾,表用于描述有层次关系的复合结构的数据。整个CLASS文件本质上也是一张表。
类型 |
名称 |
数量 |
u4 |
magic |
1 |
u2 |
minor_version |
1 |
u2 |
major_version |
1 |
u2 |
constant_pool_count |
1 |
cp_info |
constant_pool |
constant_pool_count-1 |
u2 |
access_flags |
1 |
u2 |
this_class |
1 |
u2 |
super_class |
1 |
u2 |
interfaces_count |
1 |
u2 |
interfaces |
interfaces_count |
u2 |
field_count |
1 |
field_info |
fields |
field_count |
u2 |
method_count |
1 |
method_info |
methods |
method_count |
u2 |
attribute_count |
1 |
attribute_info |
attributes |
attribte_count |
魔数(magic)(4个字节)
0xCAFEBABE
次版本号(2个字节)
主版本号(2个字节)
高版本号的JDK可以向下兼容,但不能运行版本高于自己的CLASS文件。
常量池计数器(2个字节)
计数器从1而不是0开始,0x0016,十进制为22,代表有21个常量。索引为1~21.没有使用0索引是因为在后面某些指向常量池的索引可以通过0索引表示不引用任何一个常量池项目的意思。
常量池
常量池中主要存放两大类常量:字面量(Literal)和符号引用(Symbolic References)
字面量的例子有文本字符串,被声明为final的常量值等。
符号引用包含三类常量:
- 类和接口的全限定名
- 字段的名称和描述符
- 方法的名称和描述符
JAVA代码在进行JAVAC编译时,并不像C和C++那样有连接这一步骤,而是在虚拟机加载CLASS文件的时候进行动态连接。也就是说,在CLASS文件中不会保存各个方法和字段的最终内存布局信息,因此这些字段和方法的符号引用不经过转换的话是无法直接被虚拟机使用的。当虚拟机运行时,需要从常量池获得对应的符号引用,在类创建时或运行时解析时解析并翻译到具体的内存地址中。
常量池中每一项常量都是一个表,共有11种,表开始的第一位都是一个字节的标志位,表明这个常量属于哪种类型。
JAVA程序中不能定义超过64KB英文字符的变量和方法名,否则无法编译
使用JAVAP工具可以分析class文件字节码
javap -verbose TestClass
访问标志
用于识别一些类或接口的访问信息,包括这个CLASS是类还是接口,是否为public,是否为abstract等
类索引、父类索引与接口索引集合
用来确定继承关系
字段表集合
用于描述接口或类中声明的变量。字段field包括了类级变量或实例级变量,但不包括在方法内部声明的变量。不包括方法内部声明的变量.描述了该字段是否是Public,private, protected, static,final,volatile,transient等
描述符用来描述字段的数据类型,方法的参数列表和返回值.用表示标识字符表示,对象类型用L+对象的全限定名表示
方法表集合
描述方法
包括访问标志,名称索引,描述符索引,属性表索引。方法中的代码储存在方法属性表集合中一个名为Code的属性中。
在JAVA虚拟机规范中,要重载一个方法,除了要与原方法具有相同的简单名称外,还要求必须拥有一个与原方法不同的特征签名,特征签名在JAVA代码层面和字节码层面有不同的定义。代码层面的签名只包括方法名称,参数顺序及参数类型,字节码层面还包括方法返回值和异常表。因此在CLASS文件中,如果两个方法有相同的名称和特征签名,但返回值不同,是合法的。
属性表集合
属性表集合的限制较少,不要求各个属性表有严格的顺序,并且只要不与已有的属性名重复,任何人实现的编译器都可以向属性表中写入自己定义的属性信息。JAVA虚拟机在运行时会忽略掉它不认识的属性。JAVA虚拟机规范中预定义了9项虚拟机实现应当能识别的属性:
属性名称 |
使用位置 |
含义 |
Code |
方法名 |
JAVA代码编译成的字节码指令 |
ConstantValue |
字段表 |
final关键字定义的常量值 |
Deprecated |
类,方法表,字段表 |
被声明为deprecated的方法和字段 |
Exceptions |
方法表 |
方法抛出的异常 |
InnerClasses |
类文件 |
内部类列表 |
LineNumberTable |
Code属性 |
Java源码的行号与字节码指令的对应关系 |
LocalVariableTable |
Code属性 |
方法的局部变量描述 |
SourceFile |
类文件 |
源文件名称 |
Synthetic |
类,方法表,字段表 |
标识方法或字段为编译器自动生成的 |
Code属性
JAVA程序方法体中的代码经过Javac编译器处理之后,最终变为字节码指令存储在Code属性中。
max_stack代表操作栈深度的最大值,在方法执行的任何时刻,操作数栈都不会超过这个深度,虚拟机运行的时候需要根据这个值来分配栈帧中的操作栈深度。
max_locals代表局部变量表所需的存储空间,单位为slot,对于byte,char,float,int,short,boolean,reference和returnAddress每个局部变量占用一个slot,而double和long需要两个slot.
并不是方法中用到了多少个局部变量,就把这些局部变量所占的Slot之和作为max_locals的值,原因是局部变量表中的slot可以重用,当代码执行超过一个局部变量的作用域时,这个局部变量所占用的slot就可以被其他局部变量所使用。这个值编译器会自动计算得出
code_length和code用来存储java源程序编译后生成的字节码指令,code_length代表字节码长度,code用于存储字节码指令的一系列字节流。字节码的每个指令就是一个字节。这样可以推出,一个字节最多可以代表256条指令, 目前已经使用了约200条。
而code_length有4个字节,所以一个方法做多允许有65535条字节码指令,如果超过这个限制,javac就会拒绝编译,一般JSP可能会这个原因导致失败。
在任何实例方法中,都可以通过this关键字访问到此方法所属的对象,它的底层实现就是通过javac编译器在编译的时候把this关键字的访问转变为对一个普通方法参数的访问。
因此,任何实例方法的参数Args_size最少是1,而且locals最少也是1.而静态方法就可以为0了。
异常表实际是Java代码的一部分,从start_pc行到end_pc行出现了类型为catch_type的异常,就转到第handler_pc行处理。这四个参数就组成了异常表。
对于finally的实现,实际上就是对catch字段和前面对于任意情况都运行的异常表记录
Exceptions属性
表示方法可能抛出number_of_exceptions种受查异常,每种受查异常使用一个exception_index_table项表示
LineNumberTable属性
用于描述java源代码行号与字节码行号直接的对应关系。可以用-g:none或-g:lines选项来取消或要求生成这项信息,主要影响是报错时对战是否显示出错的行号。同时debug时无法设置断点。
LocalVariableTable属性
用于描述栈帧中局部变量表中的变量与源码中定义的变量之间的关系。也可以选择开关,关闭后果就是报错时看不到变量名称
SourceFile属性
用于记录生成这个Class文件的源码文件名称。可选
ConstantValue属性
通知虚拟机自动为静态变量赋值,只有被static关键字修饰的变量才可以使用这项属性。
在JAVA中,int x=123;和static int x=123;的区别在于,非static类型的变量(实例变量)的赋值是在实例构造器<init>方法中进行的;而对于静态变量,则有两种方式可以选择:在类构造器<clinit>方法中进行,或者使用ConstantValue属性来赋值。目前SUN JAVAC编译器的选择是如果同时使用final和static来修饰一个变量,并且这个变量的数据类型是基本类型或者String的话,就生成ConstantValue属性来进行初始化,如果这个变量没有用final修饰,或者非以上类型,则选择在<clinit>中进行初始化。
InnerClasses属性
用于记录内部类与宿主类之间的关系
Deprecated和synthetic属性
都属于标志类布尔属性。deprecated表示在代码中使用@deprecated注释进行设置。synthetic表示字段或方法不是java源码产生,而是编译器自行添加的。
分享到:
相关推荐
行业分析模板--初学者必备gl.ppt
简介随着微信的普及,小视频的流行,我们设计一款基于微信小程序端的视频社交软件 + 后台管理系统作为自己专科毕业设计----秀视频-微信小程序端(短视频社交小程序,用户可以在小程序上发布自己的短视频 并且经过我们的平台加入滤镜或者背景音乐制作出独具特色的短视频。并实现了点赞、评论、下载、分享、转发等功能的小程序)---的后台管理系统,主要实现了人员的管理,短视频的管理,背景音乐的管理,登陆注册,权限验证,单点登陆等等。 从需求分析,功能设计,前端到后台,再到数据库的设计。一点点的积累,一点点的完善,预计小程序端+后台管理系统开发周期一个月(每天更新)。 对一个开发人员来说,如果想单纯的做出这些功能,其实并不难。 难的是对于这些功能细节的把控,项目整体的友好程度,用户的体验效果;对并发的考虑,对恶意请求,对流畅度这些细节的考虑等等。
基于matlab实现麦克风阵列的声源定位,四元十字阵的matlab仿真.rar
污水处理
混淆矩阵 检测茶叶中的杂质,并利用混淆矩阵计算出精确率和误判率 小技巧的设置 在train.py和train_eager.py文件下: 1、mosaic参数可用于控制是否实现Mosaic数据增强。 2、Cosine_scheduler可用于控制是否使用学习率余弦退火衰减。 3、label_smoothing可用于控制是否Label Smoothing平滑。
基于matlab实现的一种新型的配电网潮流计算,基于前推回代法,并附有10kv配电网数据,利用新的判别手段,成功解决配电网不收敛的问题.rar
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
行业报告
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
基于matlab实现的实现图像的平移,平移量应该可调(即用一个变量保存平移量),并显示对图像“view”的处理结果。 2.编程实现图像的缩放,缩放系数可调,分别用两个变量保存水平和垂直方向的缩放系数,并显示对图像“view”的处理结果。.rar
【项目资源】:基于VB+access实现抽奖系统(系统+论文+开题报告+外文翻译+封面+中英摘要+任务书+中期检查表) 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。
ASP基于BBS系统开发与帐户安全保护的实现(源代码+设计说明书).zip
污水处理计算书
卷积神经网络 卷积神经网络_基于VGGNet实现的遥感图像分类算法
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
课程设计,污水处理设计方案
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
基于matlab实现的齿轮接触疲劳强度分析程序,机械设计中使用.rar
vue面试题30道经典
node-v6.1.0.tar