首页 > 其他 > 详细

jvm -- 白话类加载器

时间:2021-04-02 22:16:19      阅读:37      评论:0      收藏:0      [点我收藏+]

永远固定的类加载器

根类加载器 (C编写 ,是根类加载器  ,是没有指定父 类 加载器类加载器父类

ExtClassLoader(扩展类加载器 ,默认没有指定 父类加载器 )

AppClassLoader(应用类加载器 ,指定类加载器没 ExtClassLoader)

一般情况下,我们说 的结构

AppClassLoader的 父类加载器 为 ExtClassLoader ,是构造函数中指定的,使用组合表示  的类加载器

 

对于ExtClassLoader,构造函数

public ExtClassLoader(File[] var1) throws IOException {
super(getExtURLs(var1), (ClassLoader)null, Launcher.factory);
SharedSecrets.getJavaNetAccess().getURLClassPath(this).initLookupCache(this);
}

技术分享图片

其中,设置null为 父类加载器
但是我们通常认为其 父类加载器 为 根类加载器,是因为在 LoadClass时,或默认选择 父类加载器进行加载,而 对于父类为空的情况,使用 根类加载其进行加载(findBootstrapClassOrNull就是,根类加载器 也被称为BootstrapClassLoader)

 技术分享图片

 

 

getSystemClassloader (系统类加载器),再没有使用java.system.class.loader进行指定的时候,就是AppClassLoader ,参看  https://www.cnblogs.com/sxrtb/p/14611395.html

指定了 java.system.class.loader的情况下 ,一般设置 AppClassLoader为 其父类加载器 (也就是或说,可以设置 AppClassLoader 为 系统类加载器的 父类 加载器)

 当然,可以参看下面

class SystemClassLoaderAction
    implements PrivilegedExceptionAction<ClassLoader> {
    private ClassLoader parent;

    SystemClassLoaderAction(ClassLoader parent) {
        this.parent = parent;
    }

    public ClassLoader run() throws Exception {
        String cls = System.getProperty("java.system.class.loader");
        if (cls == null) {
            return parent; //由InitSystemClassLoader可知,若此处返回 , 则值为AppClassLoader
        }

        Constructor<?> ctor = Class.forName(cls, true, parent)
            .getDeclaredConstructor(new Class<?>[] { ClassLoader.class });
        ClassLoader sys = (ClassLoader) ctor.newInstance(
            new Object[] { parent }); // java.system.class.loader必须有一个接受一个ClassLoader参数的构造函数 ,将AppClassLoader传入进去
        Thread.currentThread().setContextClassLoader(sys);//设置线程上下文类加载器
        return sys;
    }
}

 

Thread.currentThread().getContextClassLoader() (线程上下文类加载器) 

这个的默认设置有两处

技术分享图片

 

 

 技术分享图片

 

 

 由于此处调用没办法调式(反正我是没有调试出来),我个人的理解是

在没有设置  java.system.class.loader 的情况下,AppClassLoader为 线程上下文类加载器

在设置  java.system.class.loader 的情况下,线程上下文类加载器 为 System.class.loader (系统类加载器)

 

自定义类加载器

若自定义类加载器设置父类加载器为null ,参考https://www.cnblogs.com/sxrtb/p/14594324.html  实际上还是还是可以访问rt.jar(由根类加载器加载的类,而由于命名空间限制,类加载器只能访问自己加载的类 及其 父类加载器加载的 类),则其实根 类加载器可以 理解为是它的 父类加载器  (同ExtClassLoader设置父类加载器为 null 的 情况相同)

若构造函数中 使用super(),本质调用

    protected ClassLoader() {//使用 系统类 加载器 创建ClassLoader
        this(checkCreateClassLoader(), getSystemClassLoader());
    }

即,设置SystemClassLoader为其 父类加载器

当然,此处可以根据 设计需要,将另外一个自定义类加载器 设置为 其 父类加载器

jvm -- 白话类加载器

原文:https://www.cnblogs.com/sxrtb/p/14612135.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!