类加载器以及双亲委派模型

Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这个过程被称作虚拟机的类加载机制。

类加载器以及双亲委派模型_第1张图片 

 

自JDK1.2以来,Java一直保持着三层类加载器、双亲委派的类加载架构。

一.存放位置

1.启动类加载器(Bootstrap Class Loader):

存放在jre\lib 目录下的 rt.jar,启动类加载器无法被Java程序直接引用。

类加载器以及双亲委派模型_第2张图片

2.扩展类加载器(Extension Class Loader):

存放在 jre\lib\ext 下,这个类加载器是在类sun.misc.Launcher$ExtClassLoader 
中以Java代码的形式实现的

类加载器以及双亲委派模型_第3张图片

 

3.应用程序类加载器(Application Class Loader):

这个类加载器由sun.misc.Launcher$AppClassLoader来实现。也称系统类加载器。

二.具体实现:

接下来我们使用代码来展示一下三者的关系

一个类被加载的过程和逆过程是这样的:

类加载器以及双亲委派模型_第4张图片

 

程序代码:

public class Car {
    public static void main(String[] args) {
        Car car = new Car();

        Class aClass = car.getClass();
        ClassLoader classLoader = aClass.getClassLoader();

        System.out.println(classLoader);             //应用程序类加载器
        System.out.println(classLoader.getParent()); //扩展类加载器
        System.out.println(classLoader.getParent().getParent());  //启动类记载器


    }
}

结果:

类加载器以及双亲委派模型_第5张图片

如果返回null,有两种可能:

(1)Java调用不到;

(2)不存在

肯定是存在的,所以是第一种情况,Java调用不到,是因为启动类加载器是用C语言写的,所以Java调用不到。

三.双亲委派模型

类加载器以及双亲委派模型_第6张图片

上图展示的各类加载器之间的层次关系被称为类加载器的“双亲委派模型”。双亲委派模型要求除了顶层的启动类加载器外,其余的类加载器都应有父类加载器。不过这里的父子关系一般不是继承的关系来实现的,而是通过组合关系来复用夫加载器的代码。

1.双亲委派模型的工作流程:

如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器,每一层次的类加载器都是如此,因此所有的加载请求最终都应该传送到最顶层的启动类加载器,只有当夫加载器反馈自己无法完成这个加载请求时,子加载器才会自己去完成加载。

比如说我们知道在启动类加载器下有个java.lang.String类,如果我们同样创建一个java.lang.String类,那么,问题就来了。

类加载器以及双亲委派模型_第7张图片

就是因为在我们的启动类加载器中有了这个类,所以,首先是启动类加载器进行加载,如果父类加载器无法加载,那么才由子加载器加载。 

双亲委派模型是保证安全的。

额外知识点:Java是在C++的基础上去掉了指针和内存管理,Java也叫C++--。

你可能感兴趣的:(jvm,jvm,类加载器,双亲委派模型)