ClassLoader的双亲委派机制
Posted bce1100
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ClassLoader的双亲委派机制相关的知识,希望对你有一定的参考价值。
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 loaded 10 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 found 21 // from the non-null parent class loader 22 } 23 24 if (c == null) { 25 // If still not found, then invoke findClass in order 26 // to find the class. 27 long t1 = System.nanoTime(); 28 c = findClass(name); 29 30 // this is the defining class loader; record the stats 31 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。
为什么要使用双亲委派机制去加载类
-
比如两个类A和类B都要加载System类:
-
如果不用委托而是自己加载自己的,那么类A就会加载一份System字节码,然后类B又会加载一份System字节码,这样内存中就出现了两份System字节码。
-
如果使用委托机制,会递归的向父类查找,也就是首选用Bootstrap尝试加载,如果找不到再向下。这里的System就能在Bootstrap中找到然后加载,如果此时类B也要加载System,也从Bootstrap开始,此时Bootstrap发现已经加载过了System那么直接返回内存中的System即可而不需要重新加载,这样内存中就只有一份System的字节码了。
-
如果有人想篡改System类,如String.java,在这种机制下这些系统的类已经被Bootstrap classLoader加载过了,就算自己重写,也总是使用Java系统提供的System,自己写的System类根本没有机会得到加载。从一定程度上防止了危险代码的植入。
以上是关于ClassLoader的双亲委派机制的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向类加载器 ClassLoader ( 加载 Android 组件的类加载器 | 双亲委派机制实例分析 )