1.简介
public class ClassLoaderTest4 { public static void main(String[] args) throws Exception {//这里重写了loadClass方法,没有按双亲委派机制向上查找,双亲委派机制被破坏 ClassLoader myLoader = new ClassLoader() { @Override public Class<?> loadClass(String name) throws ClassNotFoundException { try { String fileName = name.substring(name.lastIndexOf(".") + 1)+".class"; InputStream is = getClass().getResourceAsStream(fileName); if (is == null) { return super.loadClass(name); } byte[] b = new byte[is.available()]; is.read(b);
return defineClass(name, b, 0, b.length); } catch (IOException e) { throw new ClassNotFoundException(name); } } }; Object obj = myLoader.loadClass("com.ruoyi.weixin.user.Test.ClassLoaderTest4").newInstance(); System.out.println(obj.getClass()); Class<?> aClass = Class.forName("com.ruoyi.weixin.user.Test.ClassLoaderTest4"); System.out.println(obj instanceof com.ruoyi.weixin.user.Test.ClassLoaderTest4); System.out.println("------------------"); ClassLoader classLoader = aClass.getClassLoader(); System.out.println(classLoader); ClassLoader classLoader1 = obj.getClass().getClassLoader(); System.out.println(classLoader1); } }
执行结果
class com.ruoyi.weixin.user.Test.ClassLoaderTest4 false ------------------ sun.misc.Launcher$AppClassLoader@18b4aac2 com.ruoyi.weixin.user.Test.ClassLoaderTest4$1@2dda6444
明明obj 的类型就是class com.ruoyi.weixin.user.Test.ClassLoaderTest4,但是instanceof 的结果却是false
3.2扩展类加载器(Extension Class Loader)
这个类加载器是在类sun.misc.Launcher$ExtClassLoader中以Java代码的形式实现的。它负责加载<JAVA_HOME>\lib\ext目录中,或者被java.ext.dirs系统变量所指定的路径中所有的类库。根据“扩展类加载器”这个名称,就可以推断出这是一种Java系统类库的扩展机制,JDK的开发团队允许用户将具有通用性的类库放置在ext目录里以扩展Java SE的功能,在JDK9之后,这种扩展机制被模块化带来的天然的扩展能力所取代。由于扩展类加载器是由Java代码实现的,开发者可以直接在程序中使用扩展类加载器来加载Class文件
3.3应用程序类加载器(Application Class Loader)
这个类加载器由sun.misc.Launcher$AppClassLoader来实现。由于应用程序类加载器是ClassLoader类中的getSystem-ClassLoader()方法的返回值,所以有些场合中也称它为“系统类加载器”。它负责加载用户类路径(ClassPath)上所有的类库,开发者同样可以直接在代码中使用这个类加载器。如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器
4.双亲委派机制
4.1简介
JDK 9之前的Java应用都是由这三种类加载器互相配合来完成加载的,如果用户认为有必要,还可以加入自定义的类加载器来进行拓展,典型的如增加除了磁盘位置之外的Class文件来源,或者通过类加载器实现类的隔离、重载等功能