在硬盘上查找并通过IO读入字节码文件,使用到类时才会加载,例如调用类的 main()方法,new对象等等,在加载阶段会在内存中生成一个代表这个类的 java.lang.Class对象,作为方法区这个类的各种数据的访问入口
.class文件构成
魔数(Magic Number)
1、使用文件名后缀来区分文件类型很不靠谱,后缀可以被随便修改,可以用魔数(Magic Number)实现,根据文件内容本身来标识文件的类型;很多文件都以固定的几字节开头作为魔数,比如PDF文件的魔数是 %PDF-(十六进制 0x255044462D), png文件的魔数是 \x89PNG(十六进制0x89504E47)。<br>2、使用十六进制工具打开class文件,首先看到的是充满浪漫气息的魔数0xCAFEBABE(咖啡宝贝)
版本号(Minor&Major Version)
<div>1、在魔数之后的四个字节分别表示副版本号(Minor Version)和主版本号(MajorVersion) </div><div>2、主版本号是52(0x34),虚拟机解析这个类时就知道这是一个Java 8编译出的类</div>
常量池(Constant Pool)
常量池是类文件中最复杂的数据结构。对于JVM字节码来说,如果操作数是很常用的数字,比如0,这 些操作数是内嵌到字节码中的。如果是字符串常量和较大的整数等,class文件则会把这些操作数存储在 常量池(Constant Pool)中,当使用这些操作数时,会根据常量池的索引位置来查找。
类访问标记(Access Flag)
访问标记(Access flags),用来标识一个类为final、abstract等,由两个字节表示,总共有16个标记位可供使用
类索引(This Class)
this_class表示类索引,
超类索引(Super Class)<div></div>
super_name表示直接父类的索引
接口表索引(Interface)
<div> interfaces表示类或者接口的直接父接口</div>
字段表(Field)
字段表(fields),类中定义的字段会被存储到这个集合中,包括静态和非静态的字段
方法表(Method)
<div> 类中定义的方法会被存储在方法表,方法表也是一个变长结构。<div></div> 方法method_info结构 </div><div> 方法访问标记 </div><div> 方法名与描述符 </div><div><span style="font-size: inherit;"> 方法属性表</span></div>
属性表(Attribute)
<div> 属性表使用两个字节表示属性的个数attributes_count,接下来是若干个属性项的集合,可以看作是一 个数组,数组的每一项都是一个属性项attribute_info,数组的大小为attributes_count<div></div> ConstantValue属性ConstantValue属性出现在字段field_info中,用来表示静态变量的初始值 </div><div> Code属性Code属性是类文件中最重要的组成部分,它包含方法的字节码,除native和abstract方 法以外,每个method都有且仅有一个Code属性</div>