类加载器
类加载器的类型
类型 | 加载地址 |
---|---|
Boostrap ClassLoader(启动类加载器) | jre/lib/rt.jar |
Extension ClassLoader(启动类加载器) | jre/lib/ext/*.jar |
Application ClassLoader(启动类加载器) | CLASSPATH |
(1) Bootstrap ClassLoader(启动类加载器又称为根加载器/引导类加载器)主要加载 JAVA_HOME/jre/lib 里的jar 包,该目录下的所有 jar 包都是运行 JVM 时所必需的 jar 包。
注意:类加载器其实自身也是一个 Java 类,因此,自身类加载器需要被其他类加载器进行加载后方可使用,显然必须有一个类加载器的顶级父类(也就是 BootstrapClassLoader,该类加载器是由 C 语言代码进行开发的)是其他类加载器的父类。关键点在于,如果一个类的类加载器是 Bootstrap ClassLoader,那么该类的 getClassLoader()方法返回 null。
(2) ExtClassLoader 主要加载 Java 核心扩展类,即JAVA_HOME/jre/ext 目录下的 jar 文件。
(3) AppClassLoader 主要加载的是开发者在应用程序中编写的类,即 CLASSPATH 路径下所有的 jar 文件。
双亲委派模型
使用双亲委派模型的好处:
(1)安全性,避免用户自己编写的类动态替换 Java 的一些核心类;
(2)避免类的重复加载。
类的加载过程
自定义类加载器:
如果用户想加载一个特定目录下的类时,就要用到用户自定义的类加载器。除了启动类加载器之外,所有的类加载器都是ClassLoader 的子类。
如果要编写一个自定义类加载器 MyClassLoader,那么很自然地 MyClassLoader 就要继承自 ClassLoader 类。源码中提供了大量需要重写的方法,其中有三个方法是比较关键的:
loadClass:负责以双亲委托方式去加载类
findClass:就根据类的包路径找到 class 文件
defineClass:负责从 class 字节码中加载 Class 对象,然后 Class 对象通过反射机制才生成对象的
1.装载(加载)
类的加载由类加载器完成,类加载器通常由JVM提供,这些类加载器也是前面所有程序运行的基础,JVM提供的这些类加载器通常被称为系统类加载器。除此之外,开发者可以通过继承ClassLoader基类来创建自己的类加载器。
2.链接
1)验证阶段
验证是连接阶段的第一步,这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。
2)准备阶段
准备阶段是正式为类变量分配内存并设置类变量初始值的阶段。
3)解析阶段
虚拟机将常量池内的符号引用替换为直接引用的过程。
3.初始化阶段
类变量的赋值操作。