虚拟机规范规定了有且只有5种情况必须对类进行初始化(而加载验证准备自然需要在此之前)
1)遇到new tetstatic putstatic或者invokestatic这四条字节码指令是,如果类没有进行过初始化,则需要触发初始化
2)使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发初始化
3)当初始化一个类的时候,如果发现父类还没有进行过初始化,则需要先触发父类的初始化
4)当虚拟机启动是,用户需要制定一个要执行的主类,包含main方法的那个类,虚拟机会先初始化这个主类
5)当JDK1.7de动态语言支持室,如果java.lang.invoke.MethodHandle实例最后解析结果REF——getStatic、REF_putStatic/REF_invokeStatic
类加载的过程
“加载”是类加载过程额一个阶段
加载:主要完成以下三件事情
1)通过一个类的全限定名来获取定义此类的二进制字节流
2)将这个字节流所地标额静态存储结构转化为方法区的运行时数据结构
3)在内存生产生成代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口
充满创造力的开发人员在这个舞台上玩出了各种花样
从 zip包,从网络,运行时计算生成,从其他文件中生成,从数据库中读取
数组类,本身不通过类加载器创建,它是由java虚拟机直接创建
加载和连接阶段交叉进行
连接:::
验证:1)文件格式验证
2)元数据验证
3)字节码验证
4)符号引用验证
准备:
正式为类变量分配内存并设置类变量的初始值的阶段,这里分配内存仅包括类变量,被static修饰的变量,而不包括实例变量
解析:将虚拟机常量池内的符号引用替换为直接引用的而过程(符号引用一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能够无歧义的定位到目标即可,各种虚拟机额内存布局可以各不相同,但是他们能接受的符号引用必须都是一致的,符号引用以字面量的形式明确定义在java虚拟机规范的class文件格式中)
直接引用,可以使直接指向目标的指针,相对偏移量,或者一个能够简介定位到目标的句柄。
1)类或接口解析
2)字段解析
3)类方法解析
4)接口方法解析
初始化阶段
类加载器
类和类加载器
双亲委派模型
破坏双亲委派模型