Java虚拟机不与包括java在内的任何语言绑定,它只识别.Class文件有关,丝毫不关心.Class文件的来源是什么语言。这决定了java的无关性。
###Class类文件的结构
魔数
通过魔数来识别文件类型
常量池**:**
起始为常量池中的常量数量。
第一个字节为项目类型 第三四个字节为指向常量池的位置
第五个字节为它的数据类型
第六七个字节为它的长度
项目类型表
可以用javap字节码分析工具进行分析常量池中的内容
常量池中的17种数据类型的结构总表
####访问标志
在常量池结束以后紧接着的两个字节为访问标志,用于识别一些类或者接口层次的访问信息
访问标记
访问标志位的值:它的标志位为真的标志值进行或运算
####类索引、父类索引与接口索引集合
这个集合的大小为三个u2类型
他们的值分别指向常量池中的位置
####字段表集合
字段表用于描述接口或者类中声明的变量
字段表结构
字段访问标志
name_index为简单名,指的是没有类型和参数修饰的方法或者字段
descriptor_index为方法和字段的描述
描述符含义表
字段表第一个u2类型为容量计数器,说明这个类有几个字段表数据
接下来的一个u2类型为access_flags代表修饰符。
第三个u2类型name_index是常量类型
第四个u2类型descriptor_index指向常量池中的字符串
####方法表集合
方法表结构
方法访问标志
由于特征签名的不同,java中使用方法重载时,返回值不同也会报错。
方法表的特征签名:方法名称,参数类型,参数顺序,方法返回值,受查异常表
Java代码的特征签名:方法名称,参数类型,参数顺序
####属性表集合
java虚拟机规范定义的属性
####Code****属性
属性表结构
code属性
attribute_name_index是一项指向CONSTANT_Utf8_info型常量的索引
max_stack代表了操作数栈(Operand Stack)深度的最大值
max_locals代表了局部变量表所需的存储空间
code_length和code用来存储Java源程序编译后生成的字节码指令,虽然他是u4类型的但是《java虚拟机规范》说明一个方法不允许超过65535条字节码指令
Code属性是Class文件中最重要的一个属性,用于描述代码
异常表结构
当出现catch_type类型是跳转到handler_pc行处理。当catch_type为0时任河异常全都跳转到handler_pc
####Exception****属性
exception属性结构
exception属性在方法表中与code属性平级
####LineNumberTable****属性
LineNumberTable属性用于描述Java源码行号与字节码行号(字节码的偏移量)之间的对应关系
LineNumberTable属性结构
####LocalVariableTable及LocalVariableTypeTable****属性
LocalVariableTable属性用于描述栈帧中局部变量表的变量与Java源码中定义的变量之间的关系
LocalVariableTypeTable与LocalVariableTable非常相似,仅仅是把记录的字段描述 符的descriptor_index替换成了字段的特征签名
LocalVariableTable属性结构
local_variable_info项目结构
index是这个局部变量在栈帧的局部变量表中变量槽的位置。当这个变量数据类型是64位类型时 (double和long),它占用的变量槽为index和index+1两个。
####ConstantValue****属性
ConstantValue属性的作用是通知虚拟机自动为静态变量赋值,只有被static关键字修饰的变量(类 变量)才可以使用这项属性
####Signature****属性
如果方法使用了范型,Signature属性会记录它的类型变量和参数化类型;因为java范型采用的是擦除法,所以此属性就是弥补了无法获得对象的信息的缺陷