Java 类加载机制,什么是双亲委派、双亲委派机制是什么,带来的好处是什么、类的加载流程

本文详细解释了Java类加载的双亲委派机制,包括类加载流程(加载、连接和初始化)、类加载器的协作、以及双亲委派带来的好处,如单一职责和沙箱安全。
摘要由CSDN通过智能技术生成

类加载

当jvm启动时会出现实话根加载器,根加载器会初始化Launcher类,在Launcher类中会初始化两个类加载器,一个是AppClassLoader另一个是ExtClassLoader,它们都继承于URLClassLoader,AppClassLoader中继承了顶级父类ClassLoader的parent属性,并指向ExtClassLoader类加载器引用,当执行new、getstatic、putstatic、invokestatic等指令以及反射等情况时会将没有初始化的类进行初始化,执行ClassLoader类中的loadClass方法,首先以目标加载的对象作为锁对象,然后判断类是否被加载过,如果没有被加载过就通过父加载器去加载,调用父加载器的loadClass方法也是调用同样的方法,同样父加载器也会判断是否已经加载过这个类了,如果没有加载就再次交给父加载器去进行加载,如果父加载器无法加载,最终会逐层通过自己的类加载器去加载这个类。

 protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {	
    	//利用要创建的对象作为锁
        synchronized (getClassLoadingLock(name)) {
            // 查看这个类是否被加载过
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    if (parent != null) {
                    	//如果没有被记载过,那就交给父加载器去加载
                        c = parent.loadClass(name, false);
                    } else {
                    	//如果parent为空说明当前的类加载器是extClassLoader,extClassLoader的parent是null,根加载器是C语言实现,指向为空,直接调用C提供的方法去查询根加载器是否加载过或跟加载器去加载
                        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();
                    //调用的是URLClassLoader的findClass方法去加载类
                    c = java.net.URLClassLoader.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、顺应单一职责,每个类加载器都加载规定加载的类,不会导致重复加载。

2、沙箱安全机制,java的核心类比如rt.jar、ext包下的类,都将由根加载器以及ExtClassLoader去加载,保证java的核心类不会被篡改。

类加载流程

1、加载

将.class文件加载到内存之中存入元数据区,并在堆内存中创建相应的Class对象,这个对象指向元数据区该对象的Class类元信息。

2、连接

2.1、校验

检查.class的格式以及语法是否合法。

2.2、准备

准备阶段是将为类中的静态变量划分内存空间并赋予初始值。

2.3、解析

将.class文件中都有一个常量池的区域,这个区域也被称之为静态常量池,这个常量池中存储的都是符号引用等信息,将calss文件加载到内存后就变成了运行时常量池,就需要把符号引用转变为直接引用,这个符号引用就是某一个方法名,例如test(),直接引用就是这个test()在内存中的地址值。

3、初始化

这个阶段是一个执行构造方法的一个阶段,这个阶段首先会去判断父类有没有初始化,如果父类没有初始化,就会先执行父类的初始化,具体顺序如下:

1、执行父类的静态变量的赋值、静态代码块。
2、执行子类的静态变量的赋值以及静态代码块的执行。
3、执行父类的成员变量以及实例初始化代码块。
4、执行父类的构造方法。
5、执行子类的成员变量与实例初始化代码块。
6、执行子类的构造方法。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一码归一码@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值