双亲委派机制及其部分源码分析

双亲委派机制

双亲委派机制: 我理解的 双亲委派机制 简单来讲就是,类加载器加载类的时候是 自顶向下 的过程来加载。详情如下:

在某个加载器进行类加载是,会逐级向上找到他最终的父类,BootstrapClassLoader 先进行加载,逐级向下进行加载,如果某个父类加载过了则不会重新在加载,如果所有的父类都没有加载过,最后再由自己来进行加载。

类加载器的子父级关系如下(由子到父):
用户自定义类加载器 ->> appClassLoader ->> extClassLoader ->> BootstrapClassLoader

BootstrapClassLoader:根类加载器,负责加载java的核心类,是C++编写的;
ExtensionClassLoader:扩展类加载器,扩展类加载器的加载路径是JDK目录下jre/lib/ext;
AppClassLoader:应用类加载器,它负责在JVM启动时加载来自java命令的-classpath选项、java.class.path系统属性或CLASSPATH环境变量所指定的jar包和类路径。程序可以通过getSystemClassLoader()来获取系统类加载器;

使用双亲委派机制的原因:一方面防止重复加载。一方面保证系统重要类被覆盖。如果我们定义了一个的类叫java.lang.String。那么他和java自带的String类已经重复了,如果加载了我们定义的String类,那么java自己的String类就会失效。在有了双亲委派机制之后,我们自己定义的类是由appClassLoader加载的,而java.lang.String是由BootStarpClassLoader已经加载过的

部分源码如下(我加了中文版注释)

protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            //第一次加载时检查该类是否已经被加载
            Class<?> c = findLoadedClass(name);
            //c==null表示该类没有被加载
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                	//如果有父类,则优先用父类进行加载。否则说明已经到了最顶层的bootstrapClassLoader,到此则开始加载
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }

				//父级加载没有成功
                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    long t1 = System.nanoTime();
                    //父级(们)都没有加载成功,尝试自己进行加载
                    c = findClass(name);

                    // this is the defining class loader; record the stats
                    //记录一些类加载器的数据
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }

打破双亲委派机制?

1, 正如上述代码描述的,如果我们重写了loadClass方法;(其实“java.” 下的任何包不会受到影响,因为已被设置为必须由BootStarpClassLoader加载,所以就算自定义类加载器加载也会失败)
2,使用线程上下文类加载器(未仔细了解,自行搜索或详见:https://blog.csdn.net/yangcheng33/article/details/52631940);

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值