类加载过程和双亲委派模型

一、类加载

类加载的流程:

1.加载:根据类名找到文件,读取文件,解析架构,把内容放到内存中,并构造出类的对象

2.链接:如果该类依赖了一些其他类,链接过程就是把依赖内容进行引入

3.初始化:初始化静态成员,并执行代码块

二、什么时候会触发某个类的加载?

a)构造该类的实例

b)调用该类的静态属性或者方法

c)使用子类时会触发父类的加载

举例:分析如下代码的执行顺序。

class AA{
    public AA(){
        System.out.println("AA.构造");
    }
    {
        System.out.println("AA.{}");
    }
    static {
        System.out.println("AA.static{}");
    }
}
 
class BB extends AA{
    //构造方法
    public BB(){
        System.out.println("BB.构造");
    }
    //普通代码块
    {
        System.out.println("BB.{}");
    }
    //静态代码块
    static {
        System.out.println("BB.static{}");
    }
}
public class Demo2 extends BB{
    public static void main(String[] args) {
        System.out.println("开始");
        new BB();
        new BB();
        System.out.println("结束");
    }
}
————————————————
版权声明:本文为CSDN博主「水果篮子~」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_42803467/article/details/120616543

1.代码先从main方法执行。main 是Demo2这个类的静态方法,就会触发Demo2的类加载。

2.BB 是 Demo2的父类,在加载Demo2之前,会先加载BB

3.AA 又是BB 的父类,加载BB 之前又会先加载AA

综上加载AA-》加载BB-》加载Demo2-》执行main方法

4.加载AA 调用其中的静态代码块

5.加载BB,调用BB 的静态代码块

6.Demo2没有静态代码块了,执行main方法内容

7.new BB(),构造BB 的实例会先构造AA的实例,需要先构造AA 中的代码块和构造方法

8.第二次构造BB 同 7

9.最后打印结束

【注意】代码块的执行顺序为:先执行静态代码块,接着是普通代码块,最后是构造方法

以上代码执行的结果:

AA.static{}
BB.static{}
开始
AA.{}
AA.构造
BB.{}
BB.构造
AA.{}
AA.构造
BB.{}
BB.构造
结束

三、类加载器有哪些?

1)BootstrapClassLoader 加载标准库中的类,String,ArrayList

2)ExtensionClassLoader 加载一个特殊目录中的类

  1. ApplicationClassLoader 加载应用程序自己写的类

代码示例:

package interview;
 
/**
 * @program: java16_blogdemo
 * @description
 * @author: wenwen
 * @create: 2021-10-04 19:07
 **/
import sun.net.spi.nameservice.dns.DNSNameService;
public class Demo3 {
    public static void main(String[] args) {
        ClassLoader classLoader1 = Demo3.class.getClassLoader();
        System.out.println(classLoader1);
        ClassLoader classLoader2 = String.class.getClassLoader();
        System.out.println(classLoader2);
        ClassLoader classLoader3 = DNSNameService.class.getClassLoader();
        System.out.println(classLoader3);
    }
}

四、什么是双亲委派模型?
双亲委派模型描述的是:在类加载中,根据类名找到类的.class文件的查找过程。

三个类加载器之间存在“父子关系”(和继承无关),类加载器中有一个parent 属性,指向了自己的父亲

以加载String 类为例看双亲委派模型

给一个类名:java.lang.String,让类加载器通过类名找到对应的 class 文件

    1.先从AppClassLoader 开始

    2.AppClassLoader 不会立刻查找,而是先把类名交给它的父亲,先让父亲查找

    3.ExtClassLoader 也不会立刻进行查找,而是把类名又交给它的父亲

    4.BootstrapClassLoader 拿到类名之后,只能自己亲自查找.rt.jar, 如果找到了,就直接加载类即可,如果未找到,再把这个类名交还ExtClassLoader 来查找

    5.ExtClassLoader 再根据类名在ext 目录中查找,如果找到就加载,如果没找到,就把这个类名再还给AppClassLoader进行加载

    6.AppClassLoader 再去CLASS_PATH 环境变量,-cp指定的目录,当前目录中再去查找,如果找到了,就进行加载,如果没找到,就抛出一个ClassNotFoundException

双亲委派模型目的就是:尽量让标准库的类优先被加载,例如,在代码中创建一个java.lang.String这样的类,名字和标准库的String类相同,此时优先加载标准库的String

注意:可以违背双亲委派模型,只是标准库中的三个类加载器都要遵守,其他的类加载器不太需要遵守, 例如Tomcat 中的类加载器就没有遵守(要从webapps 目录中加载指定的webapp 的类)
————————————————
版权声明:本文为CSDN博主「水果篮子~」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_42803467/article/details/120616543

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值