JAVA类的加载机制
Java类加载分为5个过程,分别为:加载,连接(验证,准备,解析),初始化,使用,卸载。

  1. 加载
    加载主要是将.class文件(也可以是zip包)通过二进制字节流读入到JVM中。 在加载阶段,JVM需要完成3件事:
    1)通过classloader在classpath中获取XXX.class文件,将其以二进制流的形式读入内存。
    2)将字节流所代表的静态存储结构转化为方法区的运行时数据结构;
    3)在内存中生成一个该类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

2.1. 验证
主要确保加载进来的字节流符合JVM规范。验证阶段会完成以下4个阶段的检验动作:
1)文件格式验证
2)元数据验证(是否符合Java语言规范)
3)字节码验证(确定程序语义合法,符合逻辑)
4)符号引用验证(确保下一步的解析能正常执行)
2.2. 准备
准备是连接阶段的第二步,主要为静态变量在方法区分配内存,并设置默认初始值。
2.3. 解析
解析是连接阶段的第三步,是虚拟机将常量池内的符号引用替换为直接引用的过程。

  1. 初始化
    初始化阶段是类加载过程的最后一步,主要是根据程序中的赋值语句主动为类变量赋值。
    当有继承关系时,先初始化父类再初始化子类,所以创建一个子类时其实内存中存在两个对象实例。
    注:如果类的继承关系过长,单从类初始化角度考虑,这种设计不太可取。原因我想你已经猜到了。
    通常建议的类继承关系最多不超过三层,即父-子-孙。某些特殊的应用场景中可能会加到4层,但就此打住,第4层已经有代码设计上的弊端了。
  2. 使用
    程序之间的相互调用。
  3. 卸载
    即销毁一个对象,一般情况下中有JVM垃圾回收器完成。代码层面的销毁只是将引用置为null。

类加载器

JVM提供了以下3种系统的类加载器:

  • 启动类加载器(Bootstrap ClassLoader):最顶层的类加载器,负责加载 JAVA_HOME\lib 目录中的,或通过-Xbootclasspath参数指定路径中的,且被虚拟机认可(按文件名识别,如rt.jar)的类。
  • 扩展类加载器(Extension ClassLoader):负责加载 JAVA_HOME\lib\ext 目录中的,或通过java.ext.dirs系统变量指定路径中的类库。
  • 应用程序类加载器(Application ClassLoader):也叫做系统类加载器,可以通过getSystemClassLoader()获取,负责加载用户路径(classpath)上的类库。如果没有自定义类加载器,一般这个就是默认的类加载器。