JAVA ClassLoader 概要总结

概念说明

类加载器(class loader):就是读取.class文件的数据并根据读取到的数据在jvm内创建对应的Class对象。
JAVA ClassLoader 概要总结_第1张图片

ClassLoader的主要方法

JAVA ClassLoader 概要总结_第2张图片
1、我们知道java类加载机制是双亲委派,这样会导致启动加载类的加载器和实际加载类的加载器有可能会不是同一个类加载器。我们来区分下这两种类加载器

  • 类初始加载器(initiating loader):启动这个类加载动作的类加载器,是通过类加载器的loadClass来触发。
  • 类定义加载器(defining loader) :真正完成类加载工作的类加载器,通过类加载器的defineClass来实现。

2、两种类加载器的关联之处在于:一个类的定义加载器是它引用的其它类的初始加载器。如类 com.example.Outer引用了类 com.example.Inner,则由类 com.example.Outer的定义加载器负责启动类 com.example.Inner的加载过程。方法 loadClass()抛出的是 java.lang.ClassNotFoundException异常;方法 defineClass()抛出的是 java.lang.NoClassDefFoundError异常。

3、首先需要说明一下 Java 虚拟机是如何判定两个 Java 类是相同的。Java 虚拟机不仅要看类的全名是否相同,还要看加载此类的类加载器是否一样。只有两者都相同的情况,才认为两个类是相同的。

4、类加载器在成功加载某个类之后,会把得到的 java.lang.Class类的实例缓存起来。下次再请求加载该类的时候,类加载器会直接使用缓存的类的实例,而不会尝试再次加载。也就是说,对于一个类加载器实例来说,相同全名的类只加载一次,即 loadClass方法不会被重复调用。

类加载的细化过程

java.lang.ClassLoader类的方法 loadClass()是用代理模式的实现。该方法会首先调用 findLoadedClass()方法来检查该类是否已经被加载过;如果没有加载过的话,会调用父类加载器的 loadClass()方法来尝试加载该类;如果父类加载器无法加载该类的话,就调用 findClass()方法来查找该类。

因此,为了保证类加载器都正确实现代理模式,在开发自己的类加载器时,最好不要覆写 loadClass()方法,而是覆写 findClass()方法。

类加载器的结构

JAVA ClassLoader 概要总结_第3张图片
Java 中的类加载器大致可以分成两类,一类是系统提供的,另外一类则是由 Java 应用开发人员编写的。系统提供的类加载器主要有下面三个:

  • 引导类加载器(bootstrap class loader):它用来加载 Java 的核心库,是用原生代码来实现的,并不继承自 java.lang.ClassLoader。
  • 扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。
  • 系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader()来获取它。

参考文档 参考

你可能感兴趣的:(java)