类加载器

类加载器的作用

类加载的过程是在jvm之外实现的,加载就是把类的二进制.class文件加载到内存中,这个动作是用类加载器实现的。

类加载器的分类

类加载器一种是虚拟机的一部分的启动类加载器 Bootstrap ClassLoader,一种是其他的类加载器,这些加载器类是继承抽象类
java.lang.ClassLoader。
一般类加载器分为四类
1.根类加载器(BootStrap ClassLoader
类加载器负责将JAVA_HOME下的lib目录下的jar包文件加载虚拟机内存中。启动类的加载器无法被java程序直接引用,
用户在编写自定义类加载器时,如果需要把类加载的请求委派为启动类加载器,直接使用null。

2.扩展类加载器(Extension ClassLoader)
这个类的加载器是由sun.misc.Launcher$ExtClassLoader实现,它负责JAVA_HOME下的libext目录中的类库。

3.应用类加载器或者叫系统类加载器(Application ClassLoader)
这个类加载器是由sun.misc.Lanuncher$AppClassLoader实现。它负责加载用户类路径(ClASS_PATH)上所指定的类库,
开发者可以直接使用这个类加载器,如果用户没有自定义类加载器,一般情况下就是默认的类加载器

4.自定义加载器

双亲委派机制

如果一个类加载器需要接收到类加载的请求,它首先不会加载这个类,他会把类的加载请求交给父加载器去完成,每一个
层级类加载器都是如此。只有父加载器无法完成类加载的请求,子加载器才会尝试去加载。
这样做的好处路径相同的类不会重复加载到内存中,比如java.lang.Object

ClassLoader例子

如果类加载器是BootStrap ClassLoader返回的是null
获取类加载器一般有四种方式
1获取当前线程上下文类加载器
Thread.currentThread().getContextClassLoader();
2获取类的加载器
class.getClassLoader()
3.获取系统类加载器
ClassLoader.getSystemClassLoader()
4.获取工具类的类加载器,比如DriveManager

package com.learn.java.javabase.jvm.classloader;

public class ClassLoaderTest13 {
    public static void main(String[] args) {
        //返回当前线程的上下文类加载器,没有指定setContextClassLoader返回的是默认父线程的类加载器
        ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();
        System.out.println("current thread loader" + currentLoader);
        Class<?> currentClass = null;
        try {
            currentClass=Class.forName("com.learn.java.javabase.jvm.classloader.ClassLoaderTest13");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //currentClass = ClassLoaderTest13.class;
        //返回当前类的加载器Returns the class loader for the class,如果是根类加载器则返回null
        System.out.println(currentClass.getClassLoader());
        System.out.println(String.class.getClassLoader());


        //返回系统类加载器。当在运行阶段,返回的是调用的线程的上下文加载器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);

        while (null != systemClassLoader) {
            systemClassLoader = systemClassLoader.getParent();
            //classLoader=ClassLoader.getSystemClassLoader();
            System.out.println(systemClassLoader);
        }
    }
}

结果

current thread loadersun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$AppClassLoader@18b4aac2
null
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@3a71f4dd
null

原文地址:https://www.cnblogs.com/JuncaiF/p/12153580.html