博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ClassLoader的双亲委派机制
阅读量:5979 次
发布时间:2019-06-20

本文共 2569 字,大约阅读时间需要 8 分钟。

双亲委派模型工作过程是:如果一个类加载器收到类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器完成。每个类加载器都是如此,只有当父加载器在自己的搜索范围内找不到指定的类时(即ClassNotFoundException),子加载器才会尝试自己去加载。

1  public Class
loadClass(String name) throws ClassNotFoundException { 2 return loadClass(name, false); 3 } 4 5 protected Class
loadClass(String name, boolean resolve) 6 throws ClassNotFoundException 7 { 8 synchronized (getClassLoadingLock(name)) { 9 // First, check if the class has already been loaded10 Class
c = findLoadedClass(name);11 if (c == null) {12 long t0 = System.nanoTime();13 try {14 if (parent != null) {15 c = parent.loadClass(name, false);16 } else {17 c = findBootstrapClassOrNull(name);18 }19 } catch (ClassNotFoundException e) {20 // ClassNotFoundException thrown if class not found21 // from the non-null parent class loader22 }23 24 if (c == null) {25 // If still not found, then invoke findClass in order26 // to find the class.27 long t1 = System.nanoTime();28 c = findClass(name);29 30 // this is the defining class loader; record the stats31 sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);32 sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);33 sun.misc.PerfCounter.getFindClasses().increment();34 }35 }36 if (resolve) {37 resolveClass(c);38 }39 return c;40 }41 }

从源码(jdk1.8)中看loadClass这个方法,注释上已经说的很清楚了,调用findLoadedClass方法检查有没有加载过这个类,如果没有就调用parent的loadClass方法,从底层一级级往上。如果找到最后都没有ClassLoader加载过这个类,就调用findClass方法查找这个类,然后又从顶层一级级往下调用findClass方法,如果有自定义ClassLoader的话最后会走到自定义的findClass方法,最终都没找到就抛出ClassNotFoundException。

为什么要使用双亲委派机制去加载类

  1. 比如两个类A和类B都要加载System类:

  • 如果不用委托而是自己加载自己的,那么类A就会加载一份System字节码,然后类B又会加载一份System字节码,这样内存中就出现了两份System字节码。

  • 如果使用委托机制,会递归的向父类查找,也就是首选用Bootstrap尝试加载,如果找不到再向下。这里的System就能在Bootstrap中找到然后加载,如果此时类B也要加载System,也从Bootstrap开始,此时Bootstrap发现已经加载过了System那么直接返回内存中的System即可而不需要重新加载,这样内存中就只有一份System的字节码了。

  1. 如果有人想篡改System类,如String.java,在这种机制下这些系统的类已经被Bootstrap classLoader加载过了,就算自己重写,也总是使用Java系统提供的System,自己写的System类根本没有机会得到加载。从一定程度上防止了危险代码的植入。

转载于:https://www.cnblogs.com/bce1100/p/10579081.html

你可能感兴趣的文章