? 加载类时加载的第一个过程,在这个阶段,将完成三件事:
? 1)通过一个类的全限定名获取该类的二进制流
? 2)将该二进制中的静态存储结构转化为方法区运行时数据结果
? 3)在内存中生成该类的Class对象,作为该类的数据访问入口
?验证的目的就是为了确保Class文件的字节流中的信息不会危害到虚拟机,在该阶段主要完成的以下四种验证
1) 文件格式验证:验证字节流是否符合Class文件的规范,如主次版本号的是否在当前虚拟机范围内,常量池中的常量是否有不被支持的类型
2)元数据验证:对字节码描述的信息进行语义分析,如这个类是否有父类,是否集成了不被继承的类等
3)字节码验证:是整个验证阶段最复杂的一个阶段,通过验证数据流和控制留的分析,确定程序语义是否正确,主要针对方法体的验证。如方法中类型转换验证是否正确,跳转指令是否正确等。
4)符号引用验证:这个动作在后面的解析中发生主要是为了确保解析动作能正确执行。
准备阶段是为了类的静态变量分配内存并将其初始化为默认值,这些内存都将在方法区中进行分配。准备阶段不分配类中的实例变量的内存,实例变量将会在对象实例化时随着对象一起分配在java堆中
class="java" name="code"> public static int value=123;//在准备阶段value初始值为0 。在初始化阶段才会变为123 。
?该阶段主要完成符号引用到直接引用的转换动作。解析动作并不一定在初始化动作完成之前,也可能在初始化完成之后
?初始化是类加载的最后一步,前面的类加载过程中除了用户自定义的类加载器可以参与类加载 ,其余的部分都是虚拟机调用完成,而只有初始化阶段才是用户真正参与java代码初始化
?
综上所述 虚拟机把要描述的类的数据从Class文件加载到内存中,通过校验 解析准备,完成初始化,最终形成被虚拟机直接使用的java类型。
?
?一个类加载器要加载某个类时,这个类加载器首先不加载这个类,而是委托给自己的父类加载器加载,当父类加载器不能加载时,这个类加载器才进行加载这个类。
?主要有四类加载器
?1,启动类加载器,用来加载java核心类库,无法被java程序员直接使用
?2,扩展类加载器,它用来加载java的扩展类,java虚拟机的实现会提供一个扩展目录。该类加载器在此目录用查找并加载java类
?3,系统类加载器,它根据java应用的类路径(classpath)加载java类,一般来说java应用的程序都是通过它来加载完成的可以通过ClassLoader.getSystemClassLoader()来获取它
?4,用户自定义加载器,通过继承java.lang.Classloader类完成
?