ClassLoader简单理解-记录

部分内容参考至:https://www.jianshu.com/p/554c138ca0f5

很多时候在需要使用类的反射来处理问题时,都会遇到ClassLoader,但只知道这个是类加载器,却不知道有啥用,从哪来的。特此记录一下。

首先看定义,java通常有三种系统类加载器,其功能也各不相同,同时也支持自定义类加载器

启动类加载器(Bootstrap ClassLoader):

    这个类加载器负责将\lib目录下的类库加载到虚拟机内存中,用来加载java的核心库,此类加载器并不继承于java.lang.ClassLoader,不能被java程序直接调用,代码是使用C++编写的.是虚拟机自身的一部分.

扩展类加载器(Extendsion ClassLoader):

    这个类加载器负责加载\lib\ext目录下的类库,用来加载java的扩展库,开发者可以直接使用这个类加载器.

应用程序类加载器(Application ClassLoader):

    这个类加载器负责加载用户类路径(CLASSPATH)下的类库,一般我们编写的java类都是由这个类加载器加载,这个类加载器是CLassLoader中的getSystemClassLoader()方法的返回值,所以也称为系统类加载器.一般情况下这就是系统默认的类加载器.

通常从上到下的顺序如下图所示,也就是常说的双亲委派模型:

双亲委派模型

有了上面的概念,现在来写一个测试类,看下控制台的输出内容

public class TestMain1 {
    public static void main(String[] args) {
        System.out.println(TestMain1.class);
        System.out.println(TestMain1.class.getClassLoader());
        System.out.println(TestMain1.class.getClassLoader().getParent());
        System.out.println(TestMain1.class.getClassLoader().getParent().getParent());
    }
}

输出内容如下

输出的第一行就不解释了,就是类的包名+类名全路径,关键在后面三行

第二行,打印了当前类的类加载器对象,注意观察$后面的AppClassLoader,也就是双亲委派模型图中的应用类加载器

第三行打印了当前类的Parent(双亲)的类加载器对象,所以$后面的就是ExtClassLoader,也就是双亲委派模型图中的扩展类加载器

第四行打印类当前类的父类的Parent(双亲)的Parent(双亲)的类加载器,按理说应该打印启动类加载器才。遇事不决读源码,这里我特意去翻了下jdk1.8的getParent()方法的源码,如下所示

private final ClassLoader parent;//当前类加载器的双亲类加载器
...略
@CallerSensitive
public final ClassLoader getParent() {
    if (parent == null)//注意这里的parent
        return null;
    SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
        // Check access to the parent class loader
        // If the caller's class loader is same as this class loader,
        // permission check is performed.
        checkClassLoaderPermission(parent, Reflection.getCallerClass());
    }
    return parent;
}

从上面的代码可以看出,当前类加载器的双亲如果是空的话,该类加载器也直接返回空,所以启动类加载器(BootstrapClassLoader)没有partent了,那么要获取启动类加载器就会直接返回null。

明显扩展类加载器(ExtensionClassLoader)调用getParent()方法后就是指向了启动类加载器(BootstrapClassLoader),如下图所示:

所以,到这里明白了吧,我们要获取的是BootstrapClassLoader,但由于BootstrapClassLoader的parent为null,所以BoostrapClassLoader.getParent()返回的也是null。

猜你喜欢

转载自blog.csdn.net/c_o_d_e_/article/details/109726182
今日推荐