本文共 1048 字,大约阅读时间需要 3 分钟。
类加载器用于加载类。
对于任意一个类,都需要由加载它的 类加载器 和这个 类 一同确立其在Java虚拟机中的唯一性。每一个类加载器,都有一个独立的类名称空间。
由不同的类加载器加载的类必定不相等。
从虚拟机角度看,只存在两种类加载器:1. 启动类加载器。2. 其他类加载器。
从开发人员角度看,包括如下类加载器:1. 启动类加载器。2. 扩展类加载器。3. 应用程序类加载器。4. 自定义类加载器。启动类加载器(Bootstrap ClassLoader):用于加载Java API,加载<JAVA_HOME>\lib目录下的类库。
扩展类加载类(Extension ClassLoader):由sun.misc.Launcher$ExtClassLoader实现,用于加载<JAVA_HOME>\lib\ext目录下或者被java.ext.dirs系统变量指定路径下的类库。
应用程序类加载器(Application ClassLoader):也成为系统类加载器,由sun.misc.Launcher$AppClassLoader实现,用于加载用户类路径(ClassPath)上所指定的类库。
自定义类加载器:实现用户自定义加载逻辑。
各个类加载器之间是组合关系,并非继承关系。
类加载器之间的这种层次关系,称为类加载器的双亲委派模型。
双亲委派模型要求除了顶层的启动类加载器之外,其余的类加载器都应该有自己的父类加载器。
各个类加载器之间是组合关系,并非继承关系。
双亲委派模型的工作过程:
当一个类加载器收到类加载的请求,它将这个加载请求委派给父类加载器进行加载,每一层加载器都是如此,最终,所有的请求都会传送到启动类加载器中。只有当父类加载器自己无法完成加载请求时,子类加载器才会尝试自己加载。
优点:
双亲委派模型可以确保安全性,可以保证所有的Java类库都是由启动类加载器加载。如用户编写的java.lang.Object,加载请求传递到启动类加载器,启动类加载的是系统中的Object对象,而用户编写的java.lang.Object不会被加载。如用户编写的java.lang.virus类,加载请求传递到启动类加载器,启动类加载器发现virus类并不是核心Java类,无法进行加载,将会由具体的子类加载器进行加载,而经过不同加载器进行加载的类是无法访问彼此的。由不同加载器加载的类处于不同的运行时包。所有的访问权限都是基于同一个运行时包而言的。