java的类加载机制主要分为七个步骤
加载,校验,准备,解析,初始化,使用,卸载
加载:
1.根据类的全名找到对应的class文件
2.将class文件中的二进制文件读取出来,在方法区生成对应的数据结构
3.在Java堆中生成一个代表这个类的java.lang.Class对象,作为对方法区中这些数据的访问入口

校验:
Class文件中的内容是字节码,这些内容可以由任何途径产出,验证阶段的目的是保证文件内容里的字节流符合Java虚拟机规范,且这些内容信息运行后不会危害虚拟机自身的安全。

准备:
这个阶段,类的静态字段信息(即使用 static 修饰过的变量)会得到内存分配,并且设置为初始值。

解析:
这个阶段,虚拟机会把这个Class文件中,常量池内的符号引用转换为直接引用。主要解析的是 类或接口、字段、类方法、接口方法、方法类型、方法句柄等符号引用。我们可以把解析阶段中,符号引用转换为直接引用的过程,理解为当前加载的这个类,和它所引用的类,正式进行“连接“的过程。

初始化:
初始化的过程,就是执行类构造器 ()方法的过程。
当初始化完成之后,类中static修饰的变量会赋予程序员实际定义的“值”,同时类中如果存在static代码块,也会执行这个静态代码块里面的代码。

类加载器

还记得在加载阶段,通过类的全限定名,获取该类字节流数据的这个动作么,类加载器就是用来实现这个动作的。

双亲委派模型:

双亲委派模型是Java类加载器的一种工作机制,它是一种层次化的类加载器结构,其中每个类加载器都有一个父类加载器。当某个类加载器需要加载一个类时,它首先会将这个请求委派给自己的父类加载器去完成。如果父类加载器无法完成这个加载请求,子类加载器才会尝试自己去加载这个类。这个过程一直持续到顶层的启动类加载器,如果启动类加载器无法完成加载请求,就会抛出ClassNotFoundException异常。

双亲委派模型的具体工作过程如下:

  1. 当Java虚拟机启动时,会先由启动类加载器(Bootstrap ClassLoader)加载核心类库(如java.lang包),这些类库是虚拟机运行所必需的类。

  2. 当应用程序需要加载某个类时,它首先会由系统类加载器(System ClassLoader)去尝试加载这个类。如果系统类加载器无法完成这个加载请求,它会将请求委派给它的父类加载器——扩展类加载器(Extension ClassLoader)去完成。

  3. 如果扩展类加载器也无法完成加载请求,它会将请求继续委派给它的父类加载器——启动类加载器去完成。启动类加载器是虚拟机内置的类加载器,它是类加载器层次结构的最顶层,所有其它类加载器的父类加载器都是它。

  4. 如果启动类加载器仍然无法完成加载请求,就会抛出ClassNotFoundException异常。

采用双亲委派模型的好处是可以有效避免类的重复加载,同时也可以保护Java核心类库不受恶意代码的侵害。当一个类被加载时,它会优先从父类加载器的缓存中查找是否已经加载过。如果已经加载过,就直接返回缓存中的类对象,避免了重复加载。如果没有加载过,就会委派给父类加载器去完成加载请求,父类加载器也会先从它的缓存中查找是否已经加载过,以此类推,直到找到顶层的启动类加载器为止。这样可以保证类的唯一性和一致性,避免出现类的版本冲突和安全问题。

总之,双亲委派模型是Java类加载器的一种工作机制,它采用层次化的类加载器结构,并将类加载请求委派给父类加载器去完成,以此保证类的唯一性和一致性。
JAVA类加载机制-LMLPHP

05-06 00:14