JVM类加载机制---类加载器

时间:2023-03-10 02:28:55
JVM类加载机制---类加载器

一、概念
  “通过一个类的全限定名来获取描述此类的二进制字节流”,实现这个动作的代码模块成为 类加载器。

二、分类
  从java开发人员的角度出发,系统提供的类加载器大致分为如下3类:
  1、启动类加载器(Bootstrap ClassLoader)
    负责将存放在<JAVA_HOME>/lib目录中的,或者被-Xbootclasspath参数所指定的路径中的,并且是虚拟机识别的类库加载到虚拟机内存中;
  2、扩展类加载器(Extension ClassLoader)
    负责加载<JAVA_HOME>/lib/ext目录中的,或者被java.ext.dirs系统变量指定的路径中的类库,开发者可以直接使用;
    3、应用程序类加载器(Application ClassLoader)
    负责加载用户类路径(ClassPath)上所指定的类库,开发者可以直接使用

  4、双亲委派模型

    JVM类加载机制---类加载器

  1)定义:除了顶层的启动类加载器外,其余的类加载器都应当有自己的父类加载器,且加载器之间的父子关系一般不会继承,而是使用组合关系来复用父加载器的代码。

  2)工作过程:
  如果一个类加载器收到了类加载的请求,他首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父类加载器反馈自己无法完成这个加载请求(搜索范围内找不到所需的类)时,子加载器才会尝试自己去加载。

  3)实现:

protected synchronized Class<?> loadClass(String name,boolean resolve) {
//首先查看请求类是否已被加载过
Class c = findLoadedClass(name);
if(c == null){
try{
if(parent != null){
c = parent.loadClass(name,false);
} else{
c = findBootstrapClassOrNull(name);
}
}catch (ClassNotFoundException e){
//父类加载器无法完成加载请求
}
//父类无法加载时在调用本身的findClass来进行类加载
if(c == null){
c = findClass(name);
}
}
if(resolve){
resolveClas();
}
return c;
}

  步骤解析:

  先检查是否已经被加载过,若没有则调用父加载器的loadClass()方法,若父加载器为空则默认是使用启动类加载器作为父加载器,若父类加载失败,抛出ClassNotFoundException后,再调用自己的findClass()方法进行加载。