• 关于Classloader(学习笔记)


     1)类加载的过程是怎么样的?
    ①加载:根据具体需求,选择合适的加载器(Bootstrap ClassLoader不可直接获取、Extension ClassLoader、系统、自定义)来控制字节流的获取,实例化一个Class对象作为数据访问入口。
    ②连接(验证,准备,解析):(JVM)
    a.验证,在加载阶段不能保证字节流的来源就是由纯粹的java代码编译过来的,也有可能是在网络中下载的、别人给的文件、zip包等,所以要进行验证(文件格式验证、元数据验证、字节码验证、符号引用验证);
    b.准备,给类变量(静态变量)分配内存并设置初始值的阶段;(注意:类变量有无final修饰)
    c.解析,将常量池内的符号引用替换为直接引用;
    ③初始化:真正执行Java代码,只会被执行一次。这里还要通过类构造器,将指定的初始值赋予给静态变量。(注意:此时与上面在准备阶段为类变量设置初始值 不同);
     2)两个不同的类加载器加载同一个类,如何进行区分和隔离?
    双亲委派机制
    观察ClassLoader的loadClass()方法:
    public Class<?> loadClass(String name) throws ClassNotFoundException {
            return loadClass(name, false);
        }
    protected synchronized Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
        {
           Class c = findLoadedClass(name);
                if (c == null) {
            try {
                if (parent != null) {
                c = parent.loadClass(name, false);
            } else {
                c = findBootstrapClassOrNull(name);
            }
            } catch (ClassNotFoundException e) {
                }
                if (c == null) {
                c = findClass(name);
            }
        }
                if (resolve) {
                resolveClass(c);
        }
        return c;
    }
    得出:当接到加载类的请求时,先检查是否已经被加载过,判断没有被加载过后,先将加载任务委托给父加载完成类加载任务,因此所有加载请求都应该传送到启动类加载其中,只有父加载器无法完成此加载任务时抛出异常,同时自己才去加载。
    又因为各个加载器之间是一种组合的关系,都有各自的分工,不同的类加载器实例加载的话,会在方法区产生两个不同的类,彼此不可见,并且在堆中生成不同Class实例。在请求委派的过程中,每一个层次类加载器都要如上操作,实现层级委任。
    从此保证了,不同ClassLoader对象加载的同名类属于不同的类型,它们之间不能相互转化和兼容。同一类的类加载器,不同的对象加载出来的类也不是同一个类。从而达到区分和隔离的效果。

  • 相关阅读:
    SpringCloud入门须知
    24SQL FOREIGN KEY 约束
    23SQL PRIMARY KEY 约束
    python之一列表集合转为字典
    DesktopSwitcher 开发
    Distribute the App on the Website
    Apple Developer账号申请
    后端——框架——视图层框架——spring mvc——注解
    后端——框架——视图层框架——spring mvc——数据(校验,转换,格式化)
    后端——框架——视图层框架——spring mvc——ExceptionResolver
  • 原文地址:https://www.cnblogs.com/1693977889zz/p/11279837.html
Copyright © 2020-2023  润新知