1、CLASS的生命周期

Class的生命周期

image-20210819114107260

  • loading:加载
  • linking:
    • verification:验证,验证的class文件是否符合JVM规范,比如java的class文件开头的cafe babe
    • preparation:准备,这里的准备是对于静态变量给定默认值
    • resolution:解析,这个我还不知道怎么解析。。。
  • initializing:初始化,初始化了静态变量,这里会赋值,同时会调用静态方法

知识点:java文件被编译之后交给类加载器,这时会产生两个东西,一个是class,另一个则是操作这个class的对象

类加载器 - ClassLoader

image-20210819114610345

  • Bootstrap:顶层的启动类加载器,负责加载Java_HOME(JRE)目录下,lib的目录下的类库,例如Charset,是C++实现的
  • Extension:拓展类加载器,负责加载Java_HOME(JRE)目录下,lib子目录下的ext的子目录的拓展类库
  • App(application):应用程序类文件加载器,负责加载classpath中的类,也是我们写的程序代码会用到的一个加载器
  • CustomClassLoader:自定义类加载器,负责加载自定义目录中的类,写框架都得有自己的类加载器

由于以上几个类加载器都是Launcher的内部类,具体我们可以查看Launcher源码,可以得到Bootstrap、Extension、App的加载路劲,我们可以通过一段代码来观察他们各自都负责加载哪些类

    public static void main(String[] args) {
        String bootClassPath = System.getProperty("sun.boot.class.path");
        System.out.println(bootClassPath.replace(":", System.lineSeparator()));

        System.out.println("------------------");

        String extClassLoader = System.getProperty("java.ext.dirs");
        System.out.println(extClassLoader.replace(":", System.lineSeparator()));

        System.out.println("------------------");

        String appClassLoader = System.getProperty("java.class.path");
        System.out.println(appClassLoader.replace(":", System.lineSeparator()));
    }

image-20210819152912248

知识点:加载器其实不存在继承的父子关系,只有:谁的 类加载器 是谁,具体可以通过下面的代码来验证

    public static void main(String[] args) {

        Class<? extends C_1> myClass = new C_1("自定义类").getClass();
        ClassLoader classLoader = myClass.getClassLoader();
        System.out.println("自定义类的类加载器:" + classLoader);

        ClassLoader classLoader1 = classLoader.getClass().getClassLoader();
        System.out.println("自定义类的类加载器的 - 上层加载器:" + classLoader1);
    }

/*
运行结果:
自定义类的类加载器:sun.misc.Launcher$AppClassLoader@18b4aac2
自定义类的类加载器的 - 上层加载器:null
*/

类加载过程-双亲委派

首先需要知道类加载器分为了4层既Bootstrap - Extension - App - CustomClassLoader,我们简称它为B-E-A-C,这四个加载器分别维护者自己的一块缓存

一个类被编程成字节码文件后,会先调用Custom.loadClass方法,把自己load进去,假如有自定义类加载器,先询问最底层的CustomClassLoader - C,如果这个加载器在内存中没有找到这个类,那么C会询问上层加载器App - A,A同样去自己维护的内存中找这个类,如果没找到,也会询问上层加载器Extension - E,同理E没找到会问Bootstrap - B,到达最顶层加载器还是没有找到这个类时,B会委托下层加载器加载这个类,但下层加载器会根据自己自己负责的领域进行加载,比如E负责加载ext中的拓展类,如果这个类不是拓展类,那E则会委托A去加载,依次类推,直到有一个加载器加载了这个类,或者没有任何一个加载器加载这个类,就会抛出ClassNotFoundException

源码过程:findInCache -> parent.loadClass -> findClass

就几个字:向上找向下委托

image-20210819132801713

自定义类加载器

能干嘛?写框架、代码加密

怎么自定义?

1、extends ClassLoader

2、overwrite findClass() -> defineClass

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值