Class类描述的是整个类的信息,在Class类中提供的forName()方法,这个方法根据ClassPath配置的路径进行类的加载,如果说现在你的类加载路径可能是网络,文件,这个时候就必须实现类加载器,也就是ClassLoder类的主要作用。
什么是ClassLoader
首先通过Class类观察如下方法:
public ClassLoader getClassLoader()
我们来演示一个非常简单的反射程序,来观察ClassLoader的存在
package Loader;
class Member{}
public class TestDemo {
public static void main(String[] args) {
Class<?> cls=Member.class;
System.out.println(cls.getClassLoader());
System.out.println(cls.getClassLoader().getParent());
System.out.println(cls.getClassLoader().getParent().getParent());
}
}
我们来看一下我们的运行结果:
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@1540e19d
null
此时出现了了两个类加载器:ExtClassLoader(扩展类加载器),AppClassLoader(应用程序类加载器)。
那么,究竟什么才是我们的类加载器呢?
JVM设计团队把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放在java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类。实现这个动作的代码模块称之为“类加载器”。
JDK中内置的三大类加载器
Bootstarp(启动类加载器):
- 使用C++实现,是JVM里面的一部分
- 负责将存放于JAVA_HOME\lib目录下的能被JVM识别的类库加载到JVM中。(rt.jar存放了java所有基础类库,java.lang,java.util)
- 启动类加载器,无法被java程序直接引用
ExtClassLoader(扩展类加载器): - 使用java实现,并且可以被java程序直接引用
- 加载JAVA_HOME\lib\ext目录下能被识别的类库
AppClassLoader(应用程序类加载器) - 负责加载用户路径(classPath)上指定的类库
- 如果应用程序中没有自定义的类加载器,则此加载器就是java程序中默认的类加载器。
双亲委派模型: - 定义:
1、 JDK内置的三种类加载器与用户自定义类加载器之间的层次关系称为类加载器的双亲委派模型
2、要求除了顶层的父类加载器外,其余的类加载器都应有自己的父类加载器
3、执行流程:如果一个类加载器收到了类加载请求,它首先不会自己去尝试加载此类,而是把类加载请求委托给父类加载器完成,每一个层次类加载器均是如此。
只有当父类加载器无法完成加载请求时(在自己搜索范围内没有找到此类),子加载器才会尝试自己去加载
- 双亲委派模型的意义在于:
双亲委派模型保证了java程序的稳定运行。
Java中基础类库一定有顶层BootStrap类加载器加载,因此,诸如Object等核心类在各种类加载器环境下都是同一个类。
比较两个类相等的前提:这两个类必须是由同一个类加载器加载的前提下才有意义。
观察我们的ClassLoader.loadClass()方法
我们在这里不做深究,只需要知道,我们的类加载器是干什么的,它的主要是帮助我们的java程序得到稳定的运行。