类的加载指的是将编译好的class类文件中的字节码读入到内存中,将其放在方法区内并建立对应的Class对象。java
类的加载分为加载、连接、初始化,其中连接又包括验证、准备、解析三步。咱们逐个分析:bootstrap
加载是文件到内存的过程。经过类的彻底限定名查找此类字节码文件,并利用字节码文件建立一个Class对象安全
验证是对类文件内容验证。目的在于确保Class文件符合当前虚拟机要求,不会危害虚拟机自身安全。主要包括四种:文件格式验证,元数据验证,字节码验证,符号引用验证。spa
准备阶段是进行内存分配。为类变量也就是类中由static修饰的变量分配内存,而且设置初始值,这里要注意,初始值是0或者null,而不是代码中设置的具体值,代码中设置的值是在初始化阶段完成的。另外这里也不包含用final修饰的静态变量,由于final在编译的时候就会分配了。指针
解析主要是解析字段、接口、方法。主要是将常量池中的符号引用替换为直接引用的过程。直接引用就是直接指向目标的指针、相对偏移量等。对象
最后是初始化:主要完成静态块执行与静态变量的赋值。这是类加载最后阶段,若被加载类的父类没有初始化,则先对父类进行初始化。接口
只有对类主动使用时,才会进行初始化,初始化的触发条件包括建立类的实例的时候、访问类的静态方法或者静态变量的时候、Class.forName()反射类的时候、或者某个子类被初始化的时候。生命周期
类的生命周期,就是从类的加载到类实例的建立与使用,再到类对象再也不被使用时能够被GC卸载回收。这里要注意一点,由java虚拟机自带的三种类加载器加载的类在虚拟机的整个生命周期中是不会被卸载的,只有用户自定义的类加载器所加载的类才能够被卸载。内存
java自带的三种类加载器分别是:bootstrap启动类加载器、扩展类加载器和应用加载器也叫系统加载器。图右边的桔黄色文字表示各种加载器对应的加载目录。启动类加载器加载java home中lib目录下的类,扩展加载器负责加载ext目录下的类,应用加载器加载classpath指定目录下的类。虚拟机
除此以外,能够自定义类加载器。
Java的类加载使用双亲委派模式,即一个类加载器在加载类时,先把这个请求委托给本身的父类加载器去执行,若是父类加载器还存在父类加载器,就继续向上委托,直到顶层的启动类加载器,如图中蓝色向上的箭头。若是父类加载器可以完成类加载,就成功返回,若是父类加载器没法完成加载,那么子加载器才会尝试本身去加载。
这种双亲委派模式的好处,一个能够避免类的重复加载,另外也避免了java的核心API被篡改。