类的加载器和双亲委派机制
-
引导类加载器:负责加载支撑JVM运行的位于JRE的lib目录下的核心类库,比如rt.jar、charsets.jar等,java中无法获取因为它是由c++编写的。
-
扩展了加载器:负责加载支撑JVM运行的位于JRE的lib目录下的ext扩展目录中的JAR类包。
-
应用程序类加载器:负责加载ClassPath路径下的类包,主要就是加载你自己写的那。
-
自定义加载器:负责加载用户自定义路径下的类包
双亲委派加载机制
-
首先,检查一下指定名称的类是否已经加载过,如果加载过了,就不需要再加载,直接返回。
-
如果此类没有加载过,那么,再判断一下是否有父加载器;如果有父加载器,则由父加载器加载(即调用parent.loadClass(name, false);).或者是调用bootstrap类加载器来加载。
-
如果父加载器及bootstrap类加载器都没有找到指定的类,那么调用当前类加载器的findClass方法来完成类加载。
为什么要设计双亲委派机制?
-
沙箱安全机制:自己写的java.lang.String.class类不会被加载,这样便可以防止核心API库被随意篡改
-
避免类的重复加载:当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次,保证被加载类的唯一性
//AppClassLoader的loadClass方法 public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { int i = name.lastIndexOf('.'); if (i != -1) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPackageAccess(name.substring(0, i)); } } if (ucp.knownToNotExist(name)) { //检查该类是否加载过 Class<?> c = findLoadedClass(name); if (c != null) { if (resolve) { resolveClass(c); } return c; } throw new ClassNotFoundException(name); } //调用父类的loadClass方法 return (super.loadClass(name, resolve)); } //ClassLoader类的loadClass方法 实现了双亲委派机制 protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { //检查当前类加载器是否加载过该类 Class<?> c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { if (parent != null) { //如果当前加载器的parent属性不为空也就是有父加载器那么就委托给父加载器加载该类 c = parent.loadClass(name, false); } else { //如果当前加载器的父加载器为空则委托引导类加载器加载该类 c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { } if (c == null) { long t1 = System.nanoTime(); //都会调用URLClassLoader的findClass方法在加载器的类路径里查找并加载该类 这里就是区分什么加载器改加载什么路径下的类 c = findClass(name); sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了