Java类的加载机制

  当在命令行执行java XXX.class指令后,java运行程序会尝试找到JRE安装的所在目录,然后寻找jvm.dll,接着启动JVM并进行初始化动作,产生Bootstrap Loader, Bootstrap Loader会加载Extended Loader, 并设置Extended Loader的parent为Bootstrap Loader。Bootstrap Loader也会加载System Loader,并将System Loader的parent设置为Extended Loader。
  Bootatrp Loader通常由C语言编写而成,Extended Loader是由Java编写而成,实际是对应于ExtClassLoader。System Loader 是由Java编写而成,实际对应于AppClassLoader

Java类的加载机制

  Bootstrap Loader会搜索系统参数sun.boot.class.path中指定位置的类,默认是JRE所在目录的classes下的 .class文件,或lib目录下的.jar文件(例如rt.jar)中的类并加载。可以使用System.getProperty(“sun.boot.class.path”)语句来显示指定的路径。

例如在我的计算机上显示如下:
C:\Java\jdk8u161\jre\lib\resources.jar;
C:\Java\jdk8u161\jre\lib\rt.jar;
C:\Java\jdk8u161\jre\lib\sunrsasign.jar;
C:\Java\jdk8u161\jre\lib\jsse.jar;
C:\Java\jdk8u161\jre\lib\jce.jar;
C:\Java\jdk8u161\jre\lib\charsets.jar;
C:\Java\jdk8u161\jre\lib\jfr.jar;
C:\Java\jdk8u161\jre\classes

  Extended Loader会搜索系统参数java.ext.dirs中指定位置的类,默认是JRE目录下的lib\ext\classes目录下的.class文件,或lib\ext目录下的.jar文件中的类并加载。 可以使用System.getProperty(“java.ext.dirs”)语句来显示指定的路径。

例如在我的计算机上显示如下:
C:\Java\jdk8u161\jre\lib\ext;
C:\windows\Sun\Java\lib\ext

  System Loader是由Java编写而成,会搜索系统参数java.class.path中指定的位置的类,也就是classpath所指定的路径,默认是当前工作路径下的 .class文件。可以使用System.getProperty(“java.class.path”)语句来显示指定的路径。

例如在我的计算机上显示如下:
C:\Users\Administrator\IdeaProjects\excel\out\production\classes

  在加载类的时,每个类加载器会先将加载类的任务交给其parent,如果parent找不到,再由自己负责加载。所以在加载类时,会以Bootstrap Loader->Extended Loader ->System Loader的顺序来寻找类,如果找不到,就会丢出NoClassDefFondError。
  类加载器在Java中是以java.lang.ClassLoader类型存在的,每一个类被加载后,都会有一个Class的实例来代表,而每个Class的实例都会记得自己是由哪个ClassLoader 加载的。可以由Class的getClassLoader()取得加载该类的ClassLoader,而从ClassLoader的getParent()方法可以取得自己的parent。取得ClassLoader的实例之后,可以使用它的loadClass()方法来加载类。使用loadClass()方法加载类时,不会运行静态区块。静态区块的运行会等到真正使用类来创建实例时。

**注意:**ExtClassLoader的parent为null,是因为Bootstrap Loader通常由C 编写成而成,在java中没有一个实际的类来表示他,所以才会显示为null。