Java类的加载机制

类加载器

类加载器的任务是根据一个类的权限定名来读取此类的二进制流到JVM内部,然后转换成一个与目标对应的class对象。

所有的类加载器有这共同的祖师爷,叫做启动器类加载器,启动器加载类是由C++实现的,没有应用的对象,所以谁也找不到它。他负责加载JAVA_HOME/lib下面的类,或者被-Xbootclasspath参数所指定的路径中并且被虚拟机识别的类库。
扩展类加载器(Extension ClassLoader)它继承自ClassLoader,负责加载相对次要的,但又通用的类,比如说JRE下面的JAVA_HOME/lib/ext下面的类
应用程序类加载器(Application ClassLoader),父类是扩展类加载器,负责加载用户程序下的类,默认情况下我么程序中包含的类便是由该类加载。

双亲委托模型

Java类的加载机制

这个是双亲委托模型的原理,可别当成累的继承关系了。

双亲委托模型的工作原理是,当一个类收到了加载类的请求时,不是自己立马就去加载,而是请求给父类去加载,每一层的类加载都是如此,因此所有的类的加载请求都应该传到最顶层的类加载器中,所以所有的类加载都会走到启动类加载器中(虽然启动类加载器不是他们的父类),只有父类返回不能加载到这个类的请求时,才会自己去加载。
双亲委托的好处是:能够有效的保证全类的唯一性,当程序中出现很多个相同的包名类名的时候,能够保证自加载了其中某一个类。这中机制的好处是Java随着他的类加载器一起具备了一种带有有限层次的层级关系。 例如在类Java.lang.Object,他放在rt.jar中,无论哪一个类加载器要加载这个类,最终都会走到启动器类加载器中,因此所有的Object在环境中都是同一个类,相反,如果没有使用双亲委派模型的话,由各个类加载器去加载,如果用户写了一个Object类,那么系统中将会出现多个Object不同的类,Java类型体系中最基础的行为也就无法保证了,那么应用程序将会变得一片混乱。 同理 如果你编写了一个和基础jar包重名(重报名)的类,那么这个类将永远无法加载运行

虚拟机加载字节流到JVM分为加载,链接和初始化:

加载: 简单的说,类加载阶段就是由类加载器负责根据一个类的全限定名来读取此类的二进制字节流到JVM内部,并存储在运行时内存区的方法区,然后将其转换为一个与目标类型对应的java.lang.Class对象实例(Java虚拟机规范并没有明确要求一定要存储在堆区中,只是hotspot选择将Class对戏那个存储在方法区中),这个Class对象在日后就会作为方法区中该类的各种数据的访问入口。

链接,是指将创建成的类合并至 Java 虚拟机中,使之能够执行的过程,其中分为验证,准备和解析.

初始化:在java中 如果要初始化一个静态字段,我们可以直接声明赋值,也可以带静态代码块中赋值,如果直接被赋值的静态字段被final修饰,并且它的类型是基本类型或者字符串是,那么这个字段就就直接被Java标记为常量值(ConstantValue),其初始化由java虚拟机直接完成,除此之外的直接赋值和静态代码块中的代码,则会被Java编译器置于同一个方法中,并他命名为
类加载的最后一步是初始化,便是为标记为常值的字段赋值,已经执行clinit的过程,JVM通过加锁来确保clinit只会被执行一次, 只有当类初始化完成,类才进入可执行的状态。
那么类的初始化何时进行呢? JVM枚举了一下多个触发情况:

  1. 当虚拟机启动时,初始化用户指定的主类
  2. 创建一个新的对象的实例的时候,比如new,比如使用反射
  3. 调用静态方法
  4. 调用静态字段
package com.zyd.entity;

public class SingInstance {

    private SingInstance(){}

    private static class LazyHolder{
        static final SingInstance INSTANCE = new SingInstance();
    }

    public SingInstance getInstance(){
        return LazyHolder.INSTANCE;
    }
}

上面这种单利模式,就是使用虚拟机初始化过程,保证了这个实例的唯一。

欢迎关注我的公众号:
Java类的加载机制

参考: https://time.geekbang.org/column/article/f8fa020cbb2ce8206fdd3ea5bdcc33cc/share?code=VWCPGaqrS8cO5nBmectn-cXiCIs3GQTjYjAqingggI0%3D&oss_token=7b7c1d89547aebe7
https://segmentfault.com/a/1190000004597758
https://www.cnblogs.com/xiaoxian1369/p/5498817.html