美文网首页
Java虚拟机是如何加载Java类

Java虚拟机是如何加载Java类

作者: 一生逍遥一生 | 来源:发表于2020-02-03 12:30 被阅读0次

    Java语言的类型可以分为两大类:基本类型和引用类型。Java将其细分为四种:类、接口、数组类和泛型参数。由于泛型参数会在编译过程中被擦除。在类、接口和数组类中,数组类是由Java虚拟机直接生成的,其他两种则有对应的字节流。

    加载

    加载是指查找字节流,并且据此创建类的过程。对于数组类来说,它并没有对应的字节流,而是Java虚拟机直接生成的。对于其他的类来说,Java虚拟机则需要借助类加载起来完成查找字节流的过程。

    启动类加载(Bootstrap Loader)是由C++实现的,没有对应的Java对象,因此在Java中只能用null来替代。
    除了Bootstrap Loader之外,其他的类加载器都是java.lang.ClassLoader的子类,因为有对应的Java对象。这些类加载器需要先有Bootstrap Loader,加载至Java虚拟机中,方能执行类加载。

    JVM使用的是双亲委派模型:每当一个类加载接收到加载请求时,它会将请求转发给父类加载器。在父类加载器没有找到所请求的类的情况下,该类加载器才会尝试取加载。

    Java 9 之前,Bootstrap Loader负责加载最为基础、最为重要的类(jre/lib/rt.jar的类);
    ExtClassLoader负责加载扩展类(jar/lib/ext/*.jar的类);AppClassLoader负责加载应用类(classpath制定的目录或jar中的类)。

    类的加载方式分为隐士加载和显示加载。隐士加载指的是程序在使用new等方式创建对象时,会隐士地调用类的加载器把对应的类加载到JVM中。显示加载指的是通过直接调用Class.forName()方法来把所需的类加载到JVM中。

    Java语言中,类的加载是动态的,它并不会一次性将所有类全部加载后再运行,而是保证程序运行的基础类完全加载到JVM中,至于其他类,在需要时才加载。

    在Java虚拟机中,类的唯一性是由类加载器实例以及类的全名一同确定,即便是同一串字节流,经由不同的类加载器加载,也会得到两个不同的类。

    链接

    链接是指将创建成的类合并至Java虚拟机中,使之能够执行的过程。可以分为验证、准备以及解析三个阶段。

    验证阶段的目的,在于确保被加载类能够满足Java虚拟机的约束条件。

    准备阶段的目的,则是为被加载类的静态字段分配内存。

    解析阶段的目的,将这些符号引用解析成为实际引用。如果符号引用指向一个未被加载的类,或者未被加载的字段或方法,那么解析将触发这个类的加载。

    Java虚拟机规范并没有要求在链接过程中完成解析。

    初始化

    在Java代码中,如果要初始化一个静态字段,可以声明时直接赋值,也可以在静态代码块中对其赋值。
    如果直接赋值的静态字段被final所修饰,并且它的类型是基本类型或字符串时,那么该字段便会被Java编译器标记成常量值,其初始化直接由Java虚拟机完成。除此之外的直接赋值操作,所以所有静态代码块中的代码,则会被Java编译器置于同一方法中,并把它命名为<clinit>。类加载的最后一步是初始化,便是为标记为常量值的字段赋值,以及执行<clinit>方法的过程。Java虚拟机会通过加锁来确保类的<clinit>方法仅被执行一次。

    那种方式可以触发初始化:

    • 当虚拟机启动时,初始化用户制定的主类;
    • 当遇到用以新建目标类实例的new指令时,初始化new指令的目标类;
    • 当遇到调用静态方法的指令时,初始化该静态方法所在的类;
    • 当遇到访问静态字段的指令时,初始化该静态字段所在的类;
    • 子类的初始化会触发父类的初始化;
    • 如果一个接口定义了default方法,那么直接实现或者间接实现该接口的类的初始化,会触发该接口的初始化;
    • 使用反射API对莫个类进行反射调用时,初始化这个类;
    • 当初次调用MethodHandle实例时,初始化该MethodHandle指向的方法所在的类。

    由于类初始化是线程安全的,并且仅按被执行一次,因此程序可以确保多线程环境下有且仅有一个Singleton实例。

    在创建对象时,不会初始化元素;在调用时,才会真正链接和初始化。

    相关文章

      网友评论

          本文标题:Java虚拟机是如何加载Java类

          本文链接:https://www.haomeiwen.com/subject/hblhxhtx.html