首页 > 代码库 > java类加载器

java类加载器

 类的加载过程

JVM将类加载过程分为三个步骤

装载,连接,初始化,连接又分为三个步骤如下:

JVM将类加载过程分为三个步骤:装载(Load),链接(Link)和初始化(Initialize)链接又分为三个步骤,如下图所示:

技术分享

1)装载:查找并加载类的二进制数据;

2)链接:

  • 验证:确保被加载类的正确性;
  • 准备:为类的静态变量分配内存,并将其初始化为默认值;
  • 解析:把类中的符号引用转换为直接引用;

3)初始化:为类的静态变量赋予正确的初始值;

         那为什么我要有验证这一步骤呢?首先如果由编译器生成的class文件,它肯定是符合JVM字节码格式的,但是万一有高手自己写一个class文件,让JVM加载并运行,用于恶意用途,就不妙了,因此这个class文件要先过验证这一关,不符合的话不会让它继续执行的,也是为了安全考虑吧。

       准备阶段和初始化阶段看似有点牟盾,其实是不牟盾的,如果类中有语句:private static int a = 10,它的执行过程是这样的,首先字节码文件被加载到内存后,先进行链接的验证这一步骤,验证通过后准备阶段,给a分配内存,因为变量astatic的,所以此时a等于int类型的默认初始值0,即a=0,然后到解析(后面在说),到初始化这一步骤时,才把a的真正的值10赋给a,此时a=10


 类的初始化

 类什么时候才被初始化:

  • 1)创建类的实例,也就是new一个对象
  • 2)访问某个类或接口的静态变量,或者对该静态变量赋值
  • 3)调用类的静态方法
  • 4)反射(Class.forName("com.lyj.load")
  • 5)初始化一个类的子类(会首先初始化子类的父类)
  • 6JVM启动时标明的启动类,即文件名和类名相同的那个类

        只有这6中情况才会导致类的类的初始化。


类的加载

 启动JVM的时候,可以使用三个类加载器:引导(bootstarp)类加载器,扩展(extensions)类加载器,应用程序(application)类加载器。


引导类加载器:仅仅负责加载核心的Java库,比如位于<JAVA_HOME>/jre/lib目录下的vm.jarcore.jar。这个类加载器,是JVM核心部分,是用native代码写成的。

扩展类加载器:负责加载扩展路径下的代码,一般位于<JAVA_HOME>/jre/lib/ext或者通过java.ext.dirs这个系统属性指定的路径下的代码。这个类加载器是由sun.misc.Launcher$ExtClassLoader实现的。

应用类加载器: 一般来说,Java应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader()来获取它。

技术分享

如果应用程序类加载器需要加载一个类,它首先委托扩展类加载器,扩展类加载器再委托引导类加载器。如果父类加载器不能加载类,子类加载器就回在自己的库中查找这个类。基于这个特性,类加载器只负责它的祖先无法加载的类。

小结:

类加载器是java的一个创新,基本上所有的类加载器都是用java.ClassLoaderler加载的一个实例。基本目的是帮助我们理解对象的实例化过程以及对象的调用。

 

java类加载器