一个类的整个生命周期如下:

.class文件需要加载进虚拟机中,才能运行和使用这些.class文件。加载的过程,就是把.class文件加载到内存,根据.class文件在内存中创建Class对象,并对数据进行校验、解析、初始化,最终形成虚拟机可以直接使用的Java类型,这也是Java虚拟机的类加载机制。
类加载具体分为3个步骤,如下:
加载:查找字节码,并在内存中创建一个
Class对象。连接:验证类中的字节码,为新对象分配内存,并将变量的值设置为系统默认的初始值。
初始化:按照程序员的意愿进行初始化。
类加载是由类加载器完成的,选择用哪个类加载器来加载类是使用双亲委派机制来确定的。
小纸条
数组类型不通过类加载器创建,它由 Java 虚拟机直接创建。
1. 类加载过程
上图中黄色背景中的部分是类加载所需要进行的操作。
2. 什么时候会加载类
第一次使用到类的时候(比如创建类的实例、要加载子类前需要先加载父类、用到类的静态方法等)会加载类,不使用不会提前加载。
3. 用什么加载类?-类加载器
JVM中内置了三个重要的 ClassLoader,除了 BootstrapClassLoader其他类加载器均由 Java 实现且全部继承自java.lang.ClassLoader:
BootstrapClassLoader(启动类加载器) :最顶层的加载类,由
C++实现,负责加载%JAVA_HOME%/lib目录下的 jar 包和类或者被-Xbootclasspath参数指定的路径中的所有类。ExtensionClassLoader(扩展类加载器) :主要负责加载
%JRE_HOME%/lib/ext目录下的jar包和类,或被java.ext.dirs系统变量所指定的路径下的jar包。AppClassLoader(应用程序类加载器) :面向我们用户的加载器,负责加载当前应用
classpath下的所有jar包和类。

4. 选择类加载器的规则-双亲委派机制
4.1 双亲委派模型
每一个类都有一个对应它的类加载器。系统中的类加载器在协同工作的时候会默认使用 双亲委派模型。
判断。在类加载的时候,系统会首先判断当前类是否被加载过。已经被加载的类会直接返回,否则才会尝试加载。
向上委派。加载的时候,首先会把该请求委派给父类加载器的
loadClass()处理,因此所有的请求最终都应该传送到顶层的启动类加载器BootstrapClassLoader中。向下加载。当父类加载器无法处理时,才由自己来处理。当父类加载器为 null 时,会使用启动类加载器
BootstrapClassLoader作为父类加载器。

4.2 好处
防止加载同一个
.class文件保证核心
API不被篡改
双亲委派模型保证了 Java程序的稳定运行,可以防止加载同一个 .class 文件,避免类的重复加载。也保证了 Java 的核心 API 不被篡改。
小纸条
如何判断两个 class 是否相同??
JVM在判定两个class是否相同时,不仅要判断两个类名是否相同,而且要判断是否由同一个类加载器实例加载的
4.3 如何打破双亲委派
如果我们想自己写一个类加载器来加载这个类,而不是通过系统默认的类加载器来加载的话。就要自定义一个类加载器,重写loadClass()。双亲委派机制是通过类加载器 ClassLoader 中的 loadClass() 实现的。
在自定义类加载器的时候,如果不想打破双亲委派,只重写
findClass()。如果想打破双亲委派,重写
loadClass()。
典型的打破双亲委派的框架和中间件是 Tomcat 和 osgi 。