Java虚拟机中的类加载子系统,它的主要作用就是通过多种类加载器(ClassLoader)来查找和加载Class文件到Java虚拟机中。
1.类加载过程
当程序主动使用某个类时,如果该类还没有被加载到内存中,则JVM会通过加载、连接、初始化3个步骤来对类进行初始化。如果没有意外,JVM会连续完成这3个步骤,所以有时也会将这3个步骤统称为类加载或者类初始化。
1.加载
加载指的是将class文件读入到内存,并为之创建一个java.lang.class对象,也就是说,程序中使用任何类,系统都会为之创建一个java.lang.class对象。
2.连接
当类被加载后,系统会为之创建一个class对象,接着将进入连接阶段,连接阶段负责将类的二进制数据合并到 jre中。
3.初始化
初始化是为类的静态变量赋予正确的初始值。
2.类加载时机
1.创建类的实例,也就是new一个对象的时候。
2.访问某个类或接口的静态变量,或者对该静态变量赋值时。
3.调用类的静态方法。
4.反射(Class.forName(“包名”))
5.初始化一个类的子类(首先会初始化它的父类)
6.JVM启动时标明的启动类,即文件名和类名相同的那个类。
3.类加载器
一旦一个类被加载到JVM中,同一个类就不会在被加载了。在Java中,一个类用其全限定类名(包括包名和类名)作为标识,但在JVM中,一个类用其全限定类名和其类加载作为其唯一标识。即在JVM中,只有包名、类名、加载器都相同,才能称之为是同一个类。
ClassLoader的类型:(Java)
包括系统类加载器和自定义加载器。系统类:Bootstrap ClassLoader,Extensions ClassLoader和Application ClassLoader。
Bootstrap ClassLoader:根类加载器,C/C++代码实现的加载器,用于加载指定的JDK的核心类库(不能被Java代码访问)。
Extensions ClassLoader:拓展类加载器,它用于加载Java的拓展类,提供除了系统类之外的额外功能。
Application ClassLoader:应用程序类加载器,负责加载用户类路径上的指定类库,如果应用程序中没有实现自己的类加载器,一般就用它去加载应用程序中的类库。
类加载器加载Class大致过程:
类加载器是使用双亲委托模式来搜索类的,每个ClassLoader实例都有一个父类加载器的引用(不是继承关系,是包含关系),JVM内置加载Bootstrap ClassLoader本身没有父类加载器,但是可以用作其他Class Loader实例的父类加载器。
当一个Class Loader实例需要加载一个类的时候,它会在试图搜索这个类之前,它会先把这个任务委托给它的父类加载器。这个过程是由上至下依次检查的,首先由最顶层的加载器Bootstrap试图加载,如果没有加载到,则把任务交给Extensions试图加载,如果还是没有加载到,则将任务转交给App ClassLoader,如果还是没有加载到,则返回给委托的发起者,由它到指定的文件系统或者网络等待URL中加载该类。
如果他们都没有加载到这个类,则抛出ClassNotFoundException异常。否则将这个类生成一个类的定义,将它加载到内存中,最后返回这个类在内存中的Class实例对象。
(图片来源:刘望舒的安卓进阶解密)
1.ClassLoader是一个抽象类,其中定义了ClassLoader的主要功能。
2.SecureClassLoader 继承了抽象类ClassLoader,但SecureClassLoader并不是ClassLoader的实现类,而是拓展了ClassLoader
类加入了权限方面的功能,加强了ClassLoader的安全性。
3.URLClassLoader继承自SecureClassLoader,可以通过URL路径从jar文件和文件夹中加载类和资源。
4.ExtClassLoader和AppClassLoader都继承自URLClassLoader,他们都是Launcher的内部类,Launcher是Java虚拟机的入口应用,ExtClassLoader和AppClassLoader都是在Launcher中进行初始化的。
安卓中的ClassLoader:和Java类似,系统类加载器:BootClassLoader,PathClassLoader和DexClassLoader。
BootClassLoader:安卓系统用它来预加载常用类,不同是它是Java实现的。
PathClassLoader:用它来加载系统类和应用程序的类。
DexClassLoader:可以加载dex文件以及包含dex的压缩文件(apk和jar文件)。
(图片来源:刘望舒安卓进阶解密)
4.类加载机制
双亲委托模式:类加载器查找Class所采用的就是双亲委托模式,意思就是向上传递给父加载器,一直到找到返回为止,如果传递到了顶层的Bootstrap ClassLoader还是没有找到,就会向下寻找。
优点:1.避免重复加载;2.更加安全。