java 类加载器
1、类加载器
类加载器是一个用来加载类文件的类。Java源代码通过javac编译器编译成类文件。然后JVM来执行类文件中的字节码来执行程序。类加载器负责加载文件系统、网络或其他来源的类文件。有三种默认使用的类加载器:Bootstrap ClassLoader、Extension ClassLoader和System ClassLoader(或者叫作Application ClassLoader)。每种类加载器都有设定好从哪里加载类。
-
Bootstrap ClassLoader 负责加载rt.jar(JRE/lib/rt.jar)中的JDK类文件,它是所有类加载器的父加载器。Bootstrap类加载器没有任何父类加载器,如果你调用String.class.getClassLoader(),会返回null,任何基于此的代码会抛出NUllPointerException异常。Bootstrap加载器被称为初始类加载器。
-
Extension ClassLoader 将加载类的请求先委托给它的父加载器,也就是Bootstrap,如果没有成功加载的话,再从JRE/lib/ext目录下或者java.ext.dirs系统属性定义的目录下加载类,即双亲委托机制。Extension加载器由sun.misc.Launcher$ExtClassLoader实现。
-
System ClassLoader 默认的加载器(又叫作Application类加载器)。它负责从classpath环境变量中加载某些应用相关的类,classpath环境变量通常由-classpath或-cp命令行选项来定义,或者是JAR中的Manifest的classpath属性。Application类加载器是Extension类加载器的子加载器。通过sun.misc.Launcher$AppClassLoader实现。
2、双亲委托机制
当一个类加载和初始化的时候,类仅在有需要加载的时候被加载。当需要加载某个类xxx.class时,首先加载这个类的请求由Application类加载器委托给它的父类加载器Extension类加载器,然后再委托给Bootstrap类加载器。Bootstrap类加载器会先看看JRE/lib/rt.jar中是否有这个类,如果有将被加载并返回字节码;如果没有,则转到Extension类加载器,Extension类加载器会查看JRE/lib/ext目录下是否有这个类,如果这个类被Extension类加载器找到了,那么它将被加载并返回字节码。且Application类加载器不会加载这个类;如果这个类没有被Extension类加载器找到,那么将由Application类加载器从classpath中寻找。依次类推,最后到自定义类加载器指定的路径还没有找到xxx.class字节码,则抛出异常ClassNotFoundException。