什么是类加载器
类加载器负责所有类的加载,系统为所有被载入内存的类生成一个java.lang.Class实例。一旦一个类被载入到JVM中,同一个类就不会被再次载入。但是如何判断“同一个类”呢?
正如一个对象有唯一标示一样,一个被载入JVM的类也拥有唯一的标示。在Java中一个类用其全限定名(包名+类名)作为标示;但是在JVM中,一个类用其全限定名和类加载器作为唯一标示,也就是说两个类加载器加载的同名类是不同的
当JVM启动时,会形成由三个类加载器组成的初始类加载器层次结构:
Bootstrap ClassLoader:根加载器
Extension ClassLoader:扩展类加载器
System ClassLoader:系统类加载器
Bootstrap ClassLoader
引导(也称为原始或根)类加载器,它负责加载Java的核心类。在Sun的JVM中,当执行java.exe命令是,使用Xbootclasspath选项或使用-D选项指定sun.boot.class.path系统属性值可以指定加载附加的类
根类加载器肥城特殊,它并不是java.lang.ClassLoader的子类,而是有JVM自身实现的。
Extension ClassLoader
扩展类加载器,负责加载JRE的扩展目录(%JAVA_HOME%jrelibext或者有java.ext.dirs系统属性指定的目录)中JAR包的类。
通过这种方式,就可以为JAva扩展核心类以外的新功能面只要把自己开发的类打包成JAR文件,然后放入JAVA_HOMEjrelibext路径即可。
System ClassLoader
系统(应用)类加载器,它负责在JVM启动是加载 来自java命令的-classpath选项、java.class.path系统属性,或CLASSPATH环境变量所指定的JAR包和类路径。程序可以通过ClassLoader的静态方法getSystemClassLoader()来获得系统类加载器。如果没有特别指定 ,则用户自定义的类加载器都以其作为父加载器。
类加载器机制
JVM的类加载机制主要与三种:
JVM的跟类加载器并不是Java实现的,而且由于程序通常无需访问根类加载器,因此使用扩展类加载器访问父类加载会返回null。但是实际上,扩展类加载器的父类加载器是根类加载器
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// 获取系统类加载器的父类加载器:得到扩展类加载器 ClassLoader extensionLader = systemLoader.getParent(); System.out.println("扩展类加载器:" + extensionLader); System.out.println("扩展类加载器的加载路径:" + System.getProperty("java.ext.dirs")); System.out.println("扩展类加载器的parent: " + extensionLader.getParent());// 返回null
类加载器加载Class大致要8个步骤:
其中,第5、6允许重写ClassLoader的findClass()方法来实现自己的载入策略,深知重写loadClass()方法来实现自己的载入过程。
加载步骤如图所示(请放大网页查看[Ctrl+滚轮]):