jvm 类加载
****************************
类文件结构
magic:魔数,确定这个文件是否是一个被虚拟机接受的文件
minor_version
major_version:class文件的版本号
constant_pool_count
constant_pool:常量池,存储字面量和和符号引用
字面量:字符串、final常量
符号引用:类和接口的全限定名、方法和字段的名称及描述符
access_falgs:访问标志,标识类或者接口的访问信息
this_class:本类索引,确定本类的全限定名
super_class:父类索引,确定父类的全限定名
interfaces_count、interfaces:类实现的接口集合
fields_count、fields:类的字段集合
methods_count、methods:类的方法集合
attributes_count、attributes:属性表,存储字段的附加信息、方法的方法体等信息
****************************
类加载机制
类加载:虚拟机把描述类的信息加载到内存,并对数据进行检验、准备、解析、初始化,生成可以被虚拟机直接使用的java类型
主要步骤:加载、验证、准备、解析、初始化
加载:
通过类或者接口的全限定名加载二进制字节流,
将字节流的静态存储结构转化为方法区运行时的数据结构,
生成class对象,作为方法区访问这个类的入口
验证:检验字节流的数据格式符合虚拟机的要求
准备:为类变量分配内存空间,并给字段赋默认值
解析:将可以直接解析的符号引用转变为直接引用(其他符号引用在运行期解析)
初始化:为类变量赋设置的值,执行静态语句块
主动初始化:
new构造对象、调用设置static字段、调用静态方法
反射调用时,类没有初始化,要先初始化
主方法所在的类执行时,没有初始化,要先初始化主方法所在的类
子类初始化时,父类没有初始化,要先初始化父类
使用动态语言功能时,方法句柄对应的类没有初始化,要先完成初始化
不会初始化情况:
子类调用父类的静态字段,父类会初始化,子类不会初始化
使用new构造类的数组对象,不会触发类的初始化
调用类的静态常量,不会触发类的初始化
****************************
类加载器
启动类加载器:加载java_home\lib目录中,或者由-Xbootclasspath路径指定的类
拓展类加载器:加载java_home\lib\ext目录中,或者由java.ext.dirs系统变量指定路径中的类
应用程序类加载器:加载用户路径上的类
用户可以自定义类加载器
双亲委派模型:类加载器接到类加载请求,会将类加载请求一层层往上抛到启动类加载器,由启动类加载器加载类,如果启动类加载器无法加载,将类加载请求抛给子类,直到能够加载为止