Java中的ClassLoader机制
大家都知道Java中的Class都是由ClassLoader加载的,先来看看ClassLoader的官方介绍。
A class loader is an object that is responsible for loading classes. The class ClassLoader is an abstract class. Given the binary name of a class, a class loader should attempt to locate or generate data that constitutes a definition for the class. A typical strategy is to transform the name into a file name and then read a "class file" of that name from a file system.
大致的意思是说:Classloader 是用来加载Java类的。定位和读取给定名字的的类,通过文件系统读入并组装成Java中的Class对象。
JDK中的ClassLoader
Bootstrap ClassLoader(启动类加载器)负责将%JAVA_HOME%/lib目录中的jar文件,或者lib下classes目录的类文件加载到JVM。Bootstrap ClassLoader是用C/C++实现的。Extension ClassLoader(扩展类加载器)负责加载%JAVA_HOME%/lib/ext中的所有类库,这个加载器其实没有父加载器的(JDK1.8)。Application ClassLoader:也称为System ClassLoaer(加载%CLASSPATH%路径的类库),默认情况下,它是加载用户自定义的类,通常它是用户创建的ClassLoader的父ClassLoader。
JDK的classloader
类加载器的双亲委托机制:当classloader要加载一个类的时候,首先从自己已经加载的类中查询是否此类已经加载,如果没有他首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一个层次类加载器都是如此,因此所有的加载请求都应该传送到启动类加载中,只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的Class),子类加载器才会尝试自己去加载,加载成功放入自己的缓存中
源码中的ClassLoader
在Launcher中可以看到JDK的ClassLoader,ExtClassLoader和AppClassLoader是Launcher中的两个内部类并且继承于URLClassLoader。初始化ExtClassLoader的时候传入的parent为null,说明ExtClassLoader没有父类。初始化AppClassLoader的时候把ExtClassLoader当作parent传入,ExtClassLoader就是AppClassLoader的parent。
Launcher中的classloader
在ClassLoader的loadClass方法中可以看到双亲委派机制的原理,就不细说了,大家自己看一下。
loadClass
在上面的方法中,如果父类加载器和启动类加载器无法加载类的时候会调用 findClass(name)方法,这个方法在ClassLoader类中是个空实现,子类必须实现,这也是自定义类加载器需要实现的一个方法。(后续会介绍怎么实现一个自定义的classloader)