
概念:加载某一个类,先委托上一级的加载器进行加载,如果上级加载器也有上级,则会继续向上委托,如果该类委托上级没有被加载,子加载器尝试加载该类。JDK 中的本地方法类一般由根加载器(Bootstrp loader)装载,JDK 中内部实现的扩展类一般由扩展加载器(ExtClassLoader )实现装载,而程序中的类文件则由系统加载器(AppClassLoader )实现装载。
源码分析:
- protected Class> loadClass(String name, boolean resolve)
- throws ClassNotFoundException
- {
- synchronized (getClassLoadingLock(name)) {
- // 首先检查这个classsh是否已经加载过了
- Class> c = findLoadedClass(name);
- if (c == null) {
- long t0 = System.nanoTime();
- try {
- // c==null表示没有加载,如果有父类的加载器则让父类加载器加载
- if (parent != null) {
- c = parent.loadClass(name, false);
- } else {
- //如果父类的加载器为空 则说明递归到bootStrapClassloader了
- //bootStrapClassloader比较特殊无法通过get获取
- c = findBootstrapClassOrNull(name);
- }
- } catch (ClassNotFoundException e) {}
- if (c == null) {
- //如果bootstrapClassLoader 仍然没有加载过,则递归回来,尝试自己去加载class
- long t1 = System.nanoTime();
- 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;
- }
- }
因为这样可以避免重复加载,当父亲已经加载了该类的时候,就没有必要子ClassLoader再加载一次。
只要我加载类的时候,不是从APPClassLoader->Ext ClassLoader->BootStrap ClassLoader 这个顺序找,那就算是打破了。
因为加载class核心的方法在LoaderClass类的loadClass方法上(双亲委派机制的核心实现)。
那只要我自定义个ClassLoader,重写loadClass方法(不依照往上开始寻找类加载器),那就算是打破双亲委派机制了。
优势:
