• 类加载器以及双亲委派机制


    1、类加载器以及双亲委派机制

      

    比如custom ClassLoader要加载一个类,会先询问它的parent类,然后AppClassLoader会看它有没有加载过这个类,如果没有继续询问它的parent即ExtensionClassLoader

    直到询问至BootstrapClassLoader也没有加载,因为BootstrapClassLoader只负责加载核心类,所以加载失败。它的child即ExtensionClassLoader就会去尝试加载,但是这个类也不在它的加载

    范围之内,也加载失败。最后就到了customlClassLoader这个加载器加载。(注意父类并不会主动调用子类去加载,而是父类加载失败后,子类再去尝试加载)。

    双亲委派机制对于保证Java程序的稳定性起了十分重要的作用,在双亲委派机制下要加载一个类最终都会委派给顶端的BootstrapClassLoader进行加载,所以如果用户自己编写一个Java.lang.Object

    类,并加载这个类并不会破坏程序的稳定性。

    ClassLoader是这些类加载器的顶层父类,下面是其中加载源码:

      

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

    由代码可以看出,加载类的时候会先自己找,没找到就找它的父加载器,父加载器也是如此,就类似于递归操作。如果没有找到合适的父加载器就调用 findClass 方法自己加载。

    1    protected Class<?> findClass(String name) throws ClassNotFoundException {
    2         throw new ClassNotFoundException(name);
    3     }

    进入findClass就直接抛出了ClassNotFoundException。但是像AppClassLoader等继承与URLClassLoader,而URLClassLoader的父类的父类就是ClassLoader,并重写了此方法。

    所以如果想自定义类加载器,就只要继承ClassLoader然后重写这个方法就行。

     

  • 相关阅读:
    【特效】导航下拉菜单(二级三级都有)
    【特效】移入显示移出隐藏
    【特效】jquery选项卡插件,页面多个选项卡统一调用
    使用MR求解多个矩阵的乘积之后
    由SequenceFile.Writer(key,value)谈toString()方法
    自定义数据类型写入SequenceFile并读出
    hadoop中URI理解
    输入格式CombineFileInput
    分布式缓存DistributedCache的使用
    输入格式MultipleInput
  • 原文地址:https://www.cnblogs.com/zcr-xiaozhai/p/13692565.html
Copyright © 2020-2023  润新知