为什么80%的码农都做不了架构师?>>>
引导类加载器(bootstrap class loader):它用来加载 Java 的核心库,是用原生代码来实现的,并不继承自 java.lang.ClassLoader。
扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。
系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader() 来获取它。
首先需要说明一下 Java 虚拟机是如何判定两个 Java 类是相同的。Java 虚拟机不仅要看类的全名是否相同,还要看加载此类的类加载器是否一样。
方法 loadClass() 抛出的是 java.lang.ClassNotFoundException 异常;方法 defineClass() 抛出的是 java.lang.NoClassDefFoundError 异常。
对于一个类加载器实例来说,相同全名的类只加载一次,即 loadClass 方法不会被重复调用。
一般来说,自己开发的类加载器只需要覆写 findClass(String name) 方法即可。
java.lang.ClassLoader 类的方法 loadClass() 封装了前面提到的代理模式的实现。
该方法会首先调用 findLoadedClass() 方法来检查该类是否已经被加载过;
如果没有加载过的话,会调用父类加载器的 loadClass() 方法来尝试加载该类;
如果父类加载器无法加载该类的话,就调用 findClass() 方法来查找该类。
因此,为了保证类加载器都正确实现代理模式,在开发自己的类加载器时,最好不要覆写 loadClass() 方法,而是覆写 findClass()方法。