类加载机制与类加载器。

类加载机制:

  一、概念:虚拟机将Class文件加载到内存,并对数据进行校验、解析和初始化,最终形成可以被虚拟机直接使用的Java类型的机制。

  二、类的生命周期:类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载、验证、准备、解析、初始化、使用、卸载。

  三、初始化的条件,加载、验证、准备、解析,其实都是为了使用这个类做准备,也就是为了初始化这个类而做准备。虚拟机规范规定,有且只有以下五种情况,才对类进行初始化。

    1、使用new关键字实例化对象。

    2、读取或设置一个类的静态字段(被final修饰、已在编译期将结果放入常量池的静态字段除外),或调用一个类的静态方法。

    3、对类进行反射。

    4、初始化子类时,优先触发其父类的初始化。

    5、虚拟机启动时,会初始化主类(包含main方法的类)。

    注意:以上是对于一个类的主动引用,会进行初始化。除此之外的引用方法(被动引用)都不会出发初始化。(比如,对于静态字段,只有直接定义该字段的类才会被初始化,而通过其子类来引用父类中定义的静态字段,只

         会触发父类的初始化,而不会出发子类的初始化。   

  四、类加载的过程:当需要初始化一个类的时候就会触发上面说的一系列加载过程。

    1、加载:在加载阶段,虚拟机会完成一下三件事情:

      i:通过一个类的全限定类名来获取此类的二进制字节流。

      ii:将这个字节流代表的静态存储结果转化为方法区的运行时数据结构。

      iii:生成代表这个类的Class对象,作为方法区中,这个类的访问入口。

    2、验证:该阶段的目的是确保Class文件的字节流中的信息是符合虚拟机要求的。

    3、准备:准备阶段是正式为类变量(被static修饰的变量)分配内存并设置初始值(零值)的阶段,这些变量所使用的内存都将在方法区进行分配。

    4、解析:解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。

    5、初始化:初始化阶段是执行构造器<clinit>() 方法(由编译器产生)的过程,在这个过程中将为类变量赋正确的初始值。

类加载器:

  一:概念:把类加载阶段的“通过一个类的全限定类名来获取描述此类的二进制字节流”,这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类。实现这个动作的代码模块称为“类加载器”。

  二:类与类加载器:两个类相等,当且仅当这两个类是由同一个类加载器加载的。

  三:类加载器的分类。

    i:启动类加载器(Bootstrap ClassLoader):它用来加载<JAVA_HOME>\lib目录中的,或者被-Xbootclasspath 参数所指定的类。是由C++实现的。

    ii:扩展类加载器(Extension ClassLoader):它用来加载<JAVA_HOME>\lib\ext 目录中的,或者被java.ext.dirs  系统变量指定的路径的类。

    iii:应用程序类加载器(Application ClassLoader):它用来加载用户类路径(ClassPath)上指定的类,是Java程序中默认的类加载器。

    iv:自定义类加载器:继承ClassLoader  并 重写 findClass()即可。

  四:双亲委派模型:上面四种类加载器的层次关系,称为双亲委派模型(图自己画)。

    i:双亲委派模型的工作过程:当一个类加载器要加载类时,它会先委派给父类加载器加载,父类加载器加载不了,再自己加载。

    ii:双亲委派模型的好处:基于上面这个特性,双亲委派模型能保证每个基础类都是被BootstrapClassLoader加载的,并且只加载一次,保证了Java的安全性和稳定性。

  五:破坏双亲委派模型:SPI机制,OSGi实现  等:https://zhuanlan.zhihu.com/p/54693308

posted @ 2019-11-01 16:13  张玉昊  阅读(303)  评论(0编辑  收藏  举报