基本概述
简单地说,类加载器是指根据指定的名称将类文件加载到JVM内存中并转换为类对象。根(Bootstrap )系统加载器:
没有继承java.lang.ClassLoader类。
Bootstrp加载器用c语言实现,在Java虚拟机启动后初始化,是虚拟机实现的一部分。 主要负责加载核心类库。 例如Java.lang .对象; %JAVA_HOME%/jre/lib
扩展类加载器:
用Java语言实现,从抽象类ClassLoader继承。
ExtClassLoader主要负责加载由JAVA_HOMElibext目录或java.ext.dirs系统变量指定的路径中的所有类库。 如果将用户创建的JAR文件放在此目录中,扩展类加载器将自动加载该文件。
系统(系统)系统加载器:
用Java语言实现,从抽象类ClassLoader继承。
负责加载用户类路径(classpath )上的指定类库,可以直接使用该类加载器。 通常,如果没有自定义类加载器,则缺省情况下使用此加载器。
与父子载入器不是继承关系。 也就是说,子加载器并不一定继承父加载器。 只需将加载器传递给构造函数并将其指定为父加载器。
类加载器加载过程
曾经的头发委托机制工作流程:
1 .现在的ClassLoader首先检查是否从自己加载的类中加载了该类,如果加载了,则直接返回原来加载的类。
每个类加载器都有自己的加载缓存,可以在加载一个类后将其放入缓存中,然后在下一次加载时直接返回。
2 .如果找不到加载到当前类加载器缓存中的类,则请求父类加载器加载。 父类加载器也采用同样的战略,首先查看自己的缓存,然后委托父类的父类加载到boot strp类加载器。
3 .如果未加载所有父类加载器,则加载当前类加载器,然后将其放入自己的缓存中,以便下次有加载请求时直接返回。
使用过去的头发委托模式的好处
1 .可以避免重复加载,如果父亲已经加载了该类,则子类加载器不需要重新加载。
2 .考虑到安全性,如果不使用此委托模式,我们可以随时使用自定义String动态替换java核心api中定义的类型。 虽然这存在非常大的安全隐患,但以前的头发委托方法避免了这种情况。 由于String已经在启动时加载,因此用户的自定义类无法加载自定义类加载器。
曾经的头发委托模型可以被破坏吗?
可以继承java.lang.ClassLoader类来实现自己的类加载器。
如果想要破坏以前的头发委托模型,可以改写loadclass(name )方法。 重写load类方法。 也就是说,现在请先尝试让系统类加载器加载。 只有在加载失败时才会自己加载。 因为没有优先交给父母,所以头发的委托机制崩溃了。