首先有一个概念要了解,我们通常说在jdk中,默认有三个类加载器,bootstrapClassLoader、ExtClassLoader、AppClassLoader,我们说前者是后者的父类加载器,但是实际上,这里所谓的父类加载器,并不是Java中的父子类继承关系,而是说:
AppClassLoader中有一个parentClassLoader设置的值是ExtClassLoader
ExtClassLoader中的parentClassLoader设置的是bootstrapClassLoader
我们自定义的类加载器,对应的parentClassLoader是AppClassLoader

我们如果自定义一个类加载器,默认设置的父类加载器是AppClassLoader,这个原因是在因为在初始化自定义类加载器的时候,会指定其parentClassLoader为AppClassLoader

Launcher

这个类是jre中用来启动main()方法的入口,在这个类中,我们着重关注的是初始化构造方法

public Launcher() {Launcher.ExtClassLoader var1;try {// 初始化extClassLoadervar1 = Launcher.ExtClassLoader.getExtClassLoader();} catch (IOException var10) {throw new InternalError("Could not create extension class loader", var10);}try {// 初始化appClassLoader,这里的这个赋值是比较重要的this.loader = Launcher.AppClassLoader.getAppClassLoader(var1);} catch (IOException var9) {throw new InternalError("Could not create application class loader", var9);}Thread.currentThread().setContextClassLoader(this.loader);String var2 = System.getProperty("java.security.manager");if (var2 != null) {SecurityManager var3 = null;if (!"".equals(var2) && !"default".equals(var2)) {try {var3 = (SecurityManager)this.loader.loadClass(var2).newInstance();} catch (IllegalAccessException var5) {} catch (InstantiationException var6) {} catch (ClassNotFoundException var7) {} catch (ClassCastException var8) {}} else {var3 = new SecurityManager();}if (var3 == null) {throw new InternalError("Could not create SecurityManager: " + var2);}System.setSecurityManager(var3);}
}

这个构造方法中,我目前所了解到的,就是初始化了AppClassLoader和ExtClassLoader,并且,和这篇博客相关的,我们只需要关心this.loader这个全局变量,这个全局变量存放的是AppClassLoader的对象信息

构造一个自定义类加载器

我们要自定义一个类加载器,只需要继承classLoader,并重写findClass()方法即可

class MyClassLoader extends ClassLoader {private String loadPath;public String getLoadPath() {return loadPath;}public void setLoadPath(String loadPath) {this.loadPath = loadPath;}@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {try {byte[] bytes = loadByte(name);return defineClass(name, bytes, 0, bytes.length);} catch (Exception e) {System.out.println(e.getMessage());}return null;}private byte[] loadByte(String className) throws Exception {className = className.replaceAll("\\.", "/");FileInputStream fileInputStream = new FileInputStream(loadPath + "/" + className + ".class");int available = fileInputStream.available();byte[] data = new byte[available];fileInputStream.read(data);fileInputStream.close();return data;}
}

那么,我在使用的时候,只需要调用new MyClassLoaderTest()即可

new MyClassLoaderTest()

我们说,自定义的类解析器对应的parentClassLoader,就是在空参构造函数中被赋值的
因为MyClassLoaderTest继承了ClassLoader,所以,会调用到ClassLoader的空参构造函数

protected ClassLoader() {this(checkCreateClassLoader(), getSystemClassLoader());
}
private ClassLoader(Void unused, ClassLoader parent) {this.parent = parent;if (ParallelLoaders.isRegistered(this.getClass())) {parallelLockMap = new ConcurrentHashMap<>();package2certs = new ConcurrentHashMap<>();domains =Collections.synchronizedSet(new HashSet<ProtectionDomain>());assertionLock = new Object();} else {// no finer-grained lock; lock on the classloader instanceparallelLockMap = null;package2certs = new Hashtable<>();domains = new HashSet<>();assertionLock = this;}
}

我们会发现,parentClassLoader就是getSystemClassLoader()返回的,

java.lang.ClassLoader#getSystemClassLoaderjava.lang.ClassLoader#initSystemClassLoader// 这个方法中的其他变量我们可以暂时先不关心,我们看到有获取到一个Launcher对象
private static synchronized void initSystemClassLoader() {if (!sclSet) {if (scl != null)throw new IllegalStateException("recursive invocation");sun.misc.Launcher l = sun.misc.Launcher.getLauncher();if (l != null) {Throwable oops = null;// 在这里调用其getClassLoader()方法,将返回的值,赋值给scl,而这个scl就是入参中的parentscl = l.getClassLoader();try {scl = AccessController.doPrivileged(new SystemClassLoaderAction(scl));} catch (PrivilegedActionException pae) {oops = pae.getCause();if (oops instanceof InvocationTargetException) {oops = oops.getCause();}}if (oops != null) {if (oops instanceof Error) {throw (Error) oops;} else {// wrap the exceptionthrow new Error(oops);}}}sclSet = true;}
}

这里的getClassLoader()返回的就是上面我说明的,需要特别关注的this.classLoader这个全局变量
所以,通过上面的代码,可以发现,我们自定义的类解析器,是在初始化的时候,指定了parent为AppClassLoader

自定义类加载器的父类为什么是AppClassLoader?相关推荐

  1. java的类加载器以及如何自定义类加载器

    ClassLoader作用 类加载流程的"加载"阶段是由类加载器完成的. 类加载器结构 结构:BootstrapClassLoader(祖父)–>ExtClassLoader ...

  2. Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论

    Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论 创建用户自定义的类加载器 要创建用户自定义的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的f ...

  3. java简单通讯录的实现02person类_Java自定义类加载器实现不同版本的类加载

    一 什么是类隔离技术 只要你 Java 代码写的足够多,就一定会出现这种情况:系统新引入了一个中间件的 jar 包,编译的时候一切正常,一运行就报错:java.lang.NoSuchMethodErr ...

  4. 类加载器源码、双亲委派、自定义类加载器详解

    文章目录 jdk的类加载器 双亲委派 自定义类加载器 打破双亲委派 jdk的类加载器 查看一个类的类加载器: ClassLoader classLoader = boy.class.getClassL ...

  5. 28 Java类的加载机制、什么是类的加载、类的生命周期、加载:查找并加载类的二进制数据、连接、初始化、类加载器、双亲委派模型、自定义类加载器

    28Java类的加载机制 28.1.什么是类的加载 28.2.类的生命周期 28.2.1.加载:查找并加载类的二进制数据 28.2.2.连接 28.2.3.初始化 28.3.类加载器 28.4.类的加 ...

  6. ccs加载out文件_类加载流程、类加载机制及自定义类加载器详解

    原文:juejin.im/post/5cffa528e51d4556da53d091 一.引言 当程序使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载.链接.初始化三个步骤对该类进行类加载 ...

  7. 类加载机制、双亲委派机制深度解析以及如何自定义类加载器

    文章目录 1.类加载运行的全过程 2. JVM类加载器的初始化 3.双亲委派机制 4.编写自定义类加载器 5.(Tomcat)如何打破双亲委派机制 当我们运行一个类的时候,首先要通过类加载机制把类加载 ...

  8. 面试-JVM-类加载-类加载器--自定义类加载器-JVM调优

    文章目录 ==类加载== 谈谈你对类文件结构的理解?有哪些部分组成? 谈谈你对类加载机制的了解? 编写java代码是如何运行起来的? 类加载机制 类加载各阶段的作用分别是什么? 有哪些类加载器?分别有 ...

  9. 请你详细说说类加载流程,类加载机制及自定义类加载器

    一.引言 当程序使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载.链接.初始化三个步骤对该类进行类加载. 二.类的加载.链接.初始化 1.加载 类加载指的是将类的class文件读入内存,并 ...

  10. JVM自定义类加载器在代码扩展性的实践

    一.背景 名单管理系统是手机上各个模块将需要管控的应用配置到文件中,然后下发到手机上进行应用管控的系统,比如各个应用的耗电量管控:各个模块的管控应用文件考虑到安全问题,有自己的不同的加密方式,按照以往 ...

最新文章

  1. 一次完整的抓包分析 Reserved TCP/IP Port List
  2. 三招让你从求职者中脱颖而出(转)
  3. OpenCASCADE:Modeling Algorithms模块之制作原语Making Primitives
  4. 点击页面元素,这个Vite插件竟然帮我打开了Vue组件文件!超级好用!
  5. Win7安装oracle 10 g
  6. Java项目课程03:涉及知识点
  7. 数据结构与算法之-----二叉树(二)
  8. 北理工计算机专业汇编教材,李元章_北京理工大学计算机学院
  9. [Python设计模式] 第14章 老板来了——观察者模式
  10. VIBE 运动目标检测
  11. 《Google软件测试之道》三、好的经验沉淀
  12. 微信小程序-更换头像
  13. 设计模式(一):简介
  14. MATLAB梯度和拉普拉斯算子在图像边缘检测中的应用
  15. 特殊注释标记todo的有关信息
  16. 传参时带有日期参数,@JsonFormat与@DateTimeFormat
  17. 途客圈创业记--读书笔记
  18. Display port
  19. 实验7-3-7 字符转换 (15 分)
  20. Web网页开发之问卷调查

热门文章

  1. 生活中运筹学的3个小案例_10个“乡村庭院”设计案例,生活在乡下,家家都有自己的小庭院...
  2. Kaggle Future Sales“”竞赛 XGB_model_final
  3. 466.统计重复个数
  4. 459.重复的子字符串
  5. 199.二叉树的右视图
  6. 函数模板与函数的区别
  7. MQAM(M元正交幅度调制)
  8. 浪潮信息能制造超级计算机吗,浪潮信息为中国航天探索事业出力 高性能计算技术领衔...
  9. 采样频率和带宽的关系_示波器的采样率和存储深度在实际操作有什么用?
  10. 最新关于高德地图定位失败10:定位服务启动、解决办法