【笔记】Java类加载器

类加载器负责读取Java字节码,并转换成java.lang.Class类的一个实例。

1. 类加载器的分类

站在虚拟机的角度,类加载器分为两类:一种是启动类加载器(Bootstrap ClassLoader),是虚拟机自身的一部分;另外一种就是独立于虚拟机外部的类加载器,继承自抽象类java.lang.ClassLoader。

站在Java开发人员的角度,可细分为:

  • 启动类加载器(Bootstrap ClassLoader):负责加载lt;JAVA_HOMEgt;\lib目录中的,或者由-Xbootclasspath参数指定的路径中的类库。这些类库根据文件名被虚拟机识别,如rt.jar,名字不符号的类库即使在这些目录中也不会被加载。

  • 扩展类加载器(Extension ClassLoader):负责加载lt;JAVA_HOMEgt;\lib\ext目录中的,或者被java.ext.dirs系统变量所指定的路径中的所有类库。由sun.misc.Launcher$ExtClassLoader实现。

  • 应用程序类加载器(Application ClassLoader):负责加载环境变量Classpath指定路径中的,或者被java.class.path系统变量所指定的路径中的所有类库。由sun.misc.Launcher$AppClassLoader实现。可以通过ClassLoader.getSystemClassLoader()方法的返回值得到。

  • 用户自定义类加载器:必须继承java.lang.ClassLoader,下面介绍。

2. java.lang.ClassLoader类介绍

自定义类加载器必须继承自java.lang.ClassLoader,该类的一些重要方法如下所示:

方法 说明
getParent() 返回加载器的父类加载器
loadClass(String name) 加载名称为name的类,返回的结果是 java.lang.Class类的实例。
findClass(String name) 查找名称为name的类,返回的结果是 java.lang.Class类的实例。
findLoadedClass(String name) 查找名称为name的已经被加载过的类,返回的结果是 java.lang.Class类的实例。
defineClass(String name, byte[] b, int off, int len) 把字节数组b中的内容转换成Java 类,返回的结果是 java.lang.Class类的实例。这个方法被声明为final的。
resolveClass(Class c) 链接指定的Java 类。

ClassLoader加载类的过程由loadClass()执行。按照以下优先级加载类:

  1. 调用findLoadedClass(String)检查类是否已经加载。

  2. 如果父类加载器不为空,则调用父类加载器的loadClass()方法;否则调用启动类加载器的loadClass()方法。

  3. 调用findClass(String)方法,该方法找到类对应的字节流后会调用defineClass方法。

3. 其他

  • 每一个java.lang.Class对象都包含一个指向定义该类的类加载器。

  • 对于一个同一个类文件,类加载器不同,得到的将不是同一种类型,即Class对象的equal将返回false。

  • 数组对象由Java运行时创建,数组元素为对象的数组的类加载器与其数组元素相同;数组元素为元素类型的数组的类加载器为null。

你可能感兴趣的:(【笔记】Java类加载器)