1. 类加载器有两种(下面说的父类并不是继承关系,而是包装关系):

   1.1. Java虚拟机自带的类加载器:

    1.1.1. 根类加载器(Bootstrap) --> C++编写

      1.1.1.1. 该加载器没有父加载器,它负责加载虚拟机核心类库,如java.lang.*等。

    1.1.2. 扩展类加载器(Extension)--> java编写

      1.1.2.1. 它的父类加载器是根类加载器,它从java.ext.dirs系统属性所指定的目录加载类库,或从JDK的安装目录 jre/lib/ext子目录下加载类库

      1.1.2.2. 如果把用户创建的jar文件放在这个目录下也会由扩展类加载器加载

      1.1.2.3. 它是java.lang.ClassLoader的子类

    1.1.3. 系统类加载器(System)--> java编写

      1.1.3.1. 也称之为应用类加载器(AppClassLoader),父类加载器为扩展类加载器。

      1.1.3.2. 它从环境变量classpath或者系统java.class.path所指定的目录加载类

      1.1.3.3. 它是用户自定义类加载器的默认父加载器

      1.1.3.4. 它是java.lang.ClassLoader的子类

  1.2. 用户自定义类加载器

    1.2.1. java.lang.ClassLoader(抽象类)的子类

    1.2.2. 通过继承ClassLoader,复写findClass(String name)方法来自定义类的加载方式

2. 如何获取某一个类的类加载器?getClassLoader()方法

7. 类加载机制 7.2. 类加载器

通过use null to represent the bootstrap class loader就能明白,获取类加载器返回为空的时候,说明类的类加载器就是根类加载器

package com.odao;

public class Student {
    
    public static void main(String[] args) throws ClassNotFoundException {
        Class clazz = Class.forName("java.lang.String");
        System.out.println(clazz.getClassLoader());
        
        Class clazz1 = Class.forName("com.odao.Student");
        System.out.println(clazz1.getClassLoader());
    }
}

clazz.getClassLoader()返回为:null 说明String类是由根类加载器加载的

clazz1.getClassLoader()返回为:sun.misc.Launcher$AppClassLoader@43be2d65(应用类加载器) 说明Student类的类加载器为系统加载器

 3. 父类委托机制

     JDK1.2版本开始,类的加载过程采用父亲委托机制,这种机制能更好地保证Java平台的安全。

在此委托机制中,除了Java虚拟机自带的根类加载器以外,其余的类加载器有切仅有一个父加载器

例如:当Java程序请求加载器loader1加载Sample类时,loader1首先委托自己的父加载器去加载Sample,父加载器能加载Sample,则由父加载器加载,否则才由加载器loader1本身加载Sample类

为什么都先要判断父类加载器能否加载?

假如我们自己构造了一个有风险的类(不符合Jvm规范的),然后自定义了一个类加载器来加载这个有风险的类,那么是不是就会给程序带来不安全的因素。

相关文章:

  • 2021-11-14
  • 2021-11-08
  • 2021-08-26
  • 2021-04-29
  • 2021-10-01
  • 2021-08-03
  • 2021-08-03
  • 2021-06-21
猜你喜欢
  • 2022-02-16
  • 2021-09-22
  • 2021-12-02
  • 2021-09-09
  • 2021-06-06
  • 2021-08-21
  • 2021-09-02
相关资源
相似解决方案