JJVM类的加载过程

这篇具有很好参考价值的文章主要介绍了JJVM类的加载过程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

类的加载过程

一个java文件从被加载到被卸载这个生命过程,总共要经理五个阶段,JVM将类加载过程分为:(加链初使卸

1. 加载

首先通过一个类的全限定名来获取此类的二进制字节流;其次将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构;最后在java堆中生成一个代表这个类的Class对象,作为方法区这些数据的访问入口。总的来说就是查找并加载类的二进制数据。

2. 链接

验证:确保被加载类的正确性,字节码开头必须为cafebabe

准备:为类的静态变量分配内存,并将其初始化为默认值

解析:把类中的符号引用转换为直接引用

3. 类的初始化

1> 类什么时候才被初始化
  • 创建类的实例,也就是new一个对象

  • 访问某个类或接口的静态变量,或者对该静态变量赋值

  • 调用类的静态方法

  • 反射(Class.forName(类路径))

  • 初始化一个类的子类(会首先初始化子类的父类)

  • JVM启动时标明的启动类,即文件名和类名相同的那个类

    另外:

    1、类中的static final 修饰的基本数据类型及String类型成员变量,被访问是不会触发类初始化的;

    2、静态内部类也是被访问不会触发类初始化;

2>类的初始化顺序
  1. 如果这个类还没有被加载和链接,那先进行加载和链接

  2. 假如这个类存在直接父类,并且这个类还没有被初始化(注意:在一个类加载器中,类只能初始化一次),那就初始化直接的父类(不适用于接口)

  3. 加入类中存在初始化语句(如static变量和static块),那就一次执行这些初始化语句

  4. 总的来说,初始化顺序依次是:(静态变量、静态初始化块)->(变量、初始化块)-> 构造器

如果有父类,则顺序是:

父类static方法 -> 子类static方法 -> 父类构造方法 -> 子类构造方法

4. 类的加载

类的加载指的是将类的.class文件中的二进制数据读入内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个这个类的java.lang.Class对象。

先将类的字节码文件读入内存,放入方法区中,然后在堆中创建一个该类的Class对象

如:

类的加载的最终产品是位于堆中的Class对象。Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口。加载类的方式有以下几种:

  1. 从本地系统直接加载

  2. 通过网络下载.class文件

  3. 从zip,jar等归档文件中加载.class文件

  4. 从专有数据库中提取.class文件

  5. 将Java源文件动态编译为.class文件(服务器)

5.加载器

JVM的类加载是通过ClassLoader及其子类来完成的,类的层次关系和加载顺序可以由下图来描述:

加载器介绍:

1)BootstrapClassLoader(启动类加载器)   负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,加载System.getProperty(“sun.boot.class.path”)所指定的路径或jar。 2)ExtensionClassLoader(标准扩展类加载器)   负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包。载System.getProperty(“java.ext.dirs”)所指定的路径或jar。 3)AppClassLoader(系统类加载器)   负责记载classpath中指定的jar包及目录中class 4)CustomClassLoader(自定义加载器)   属于应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现。

(2)类加载器的顺序 1)加载过程中会先检查类是否被已加载,检查顺序是自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层检查,只要某个classloader已加载就视为已加载此类,保证此类只所有ClassLoader加载一次。而加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类。 2)在加载类时,每个类加载器会将加载任务上交给其父,如果其父找不到,再由自己去加载。

3)Bootstrap Loader(启动类加载器)是最顶级的类加载器了,其父加载器为null。

public class Demo {
    public static void main(String[] args) {
        C c = new C();
    }
}
class A{
    static {
        System.out.println("A static");
    }
}
​
class B extends A{
    static {
        System.out.println("B static");
    }
}
​
class D{
    static {
        System.out.println("D static");
    }
}
​
class C extends B{
    private static D d = new D();
    static {
        System.out.println("C static");
    }
}

打印

A static
B static
D static
C static

在上面的例子中,类C继承于B,B继承于A,C又依赖于D,在创建C时,会自动加载C继承的B和依赖的D,然后B又继承于A,先加载A,再加载B,再加载D,最后加载D

继承的优先级大于依赖

所有的变量初始化完,才会执行构造方法

在类的加载过程中,只有内部的变量创建完,才会去执行这个类的构造方法。

// 静态块 和 构造方法的加载顺序
public class ConstructorStep {
    public static void main(String[] args) {
        A2 a2 = new A2();
    }
}
​
class D2{
    static {
        System.out.println("D2 static");
    }
    public D2(){
        System.out.println("D2 constructor");
    }
}
​
class C2{
    static {
        System.out.println("C2 static");
    }
    public C2(){
        System.out.println("C2 constructor");
    }
}
​
class B2{
    C2 c2 = new C2();
    D2 d2 = new D2();
    static {
        System.out.println("B static");
    }
    public B2(){
        System.out.println("B2 constructor");
    }
}
​
class A2{
    B2 b2 = new B2();
    static {
        System.out.println("A static");
    }
    public A2(){
        System.out.println("A2 constructor");
    }
}

打印:

A static
B static
C2 static
C2 constructor
D2 static
D2 constructor
B2 constructor
A2 constructor
​

先创建A,执行A的静态块,再加载A的成员变量B2

执行B2的静态块,再加载B的成员变量C2,D2

执行C2的静态块,由于C2中没有成员变量需要加载,再执行C2的空参构造方法。

执行D2的静态块,同C2一样。

B2的成员变量加载完了,执行B2的构造方法

最后,A2同B2一样


总结

  1. 所有的类都会优先加载基类

  2. 静态成员的初始化优先

  3. 成员初始化完后,才会执行构造方法

  4. 静态成员的初始化与静态块的执行,发生在类加载的时候,静态成员的优先级大于静态块

  5. 类对象的创建以及静态块的访问,都会触发类的加载

执行顺序

静态成员变量 -> 静态代码块 -> 成员变量 -> 构造方法文章来源地址https://www.toymoban.com/news/detail-847837.html

到了这里,关于JJVM类的加载过程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java语言------四种内部类的详细讲解

    目录 一.内部类的介绍 二.内部类的种类 2.1实例内部类       2.2.静态内部类 2.3局部内部类 2.4匿名内部类 总结        内部类: 一个类定义在  另一个类  的  内部。        内部类分为 四种 : 实例内部类、静态内部类、局部内部类、匿名内部类。 使用时机:当一个事

    2023年04月25日
    浏览(21)
  • 【Java】JVM执行流程、类加载过程和垃圾回收机制

    JVM,就是Java虚拟机,Java的的程序都是运行在JVM当中。 程序在执行之前先要把java源代码转换成字节码(class文件),JVM 首先需要把字节码通过一定的方(类加载器(ClassLoader)) 把文件加载到内存中的运行时数据区(Runtime Data Area) ,而字节码文件是 JVM 的一套指令集规范,并

    2024年02月16日
    浏览(15)
  • Java进阶(1)——JVM的内存分配 & 反射Class类的类对象 & 创建对象的几种方式 & 类加载(何时进入内存JVM)& 注解 & 反射+注解的案例

    1.java运行时的内存分配,创建对象时内存分配; 2.类加载的顺序,创建一个唯一的类的类对象; 3.创建对象的方式,new,Class.forName,clone; 4.什么时候加载.class文件进入JVM内存中,看到new,Class.forName; 5.如何加载?双亲委托(委派)机制:安全;AppClassLoader; 6.反射实质:能

    2024年02月14日
    浏览(16)
  • 《深入理解Java虚拟机》读书笔记: 虚拟机类加载的时机和过程

    虚拟机类加载的时机和过程 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)7个阶段。其中验证、准备、解析3个

    2024年02月12日
    浏览(10)
  • 【JAVA语言-第12话】API中的工具类 之 Date,DateFormat,SimpleDateFormat,Calendar类的详细解析

    目录 日期和时间 1.1 Date类 1.1.1 概述 1.1.2 常用方法  1.1.3 案例 1.2 DateFormat类  1.2.1 概述 1.2.2 常用方法 1.3 SimpleDateFormat类 1.3.1 概述 1.3.2 构造方法 1.3.3 模式字符  1.3.4 日期转字符串 1.3.5 字符串转日期 1.4 Calendar类 1.4.1 概述 1.4.2 静态方法 1.4.3 常用成员方法 1.4.4 成员方法中参数

    2024年02月02日
    浏览(14)
  • JVM性能优化 —— 类加载器,手动实现类的热加载

    每个编写的”.java”拓展名类文件都存储着需要执行的程序逻辑,这些”.java”文件经过Java编译器编译成拓展名为”.class”的文件,”.class”文件中保存着Java代码经转换后的虚拟机指令,当需要使用某个类时,虚拟机将会加载它的”.class”文件,并创建对应的class对象,将c

    2024年02月08日
    浏览(13)
  • JVM类的加载相关的问题

    学习类的加载的加载过程对深入理解JVM有十分重要的作用,下面就跟我一起学习JVM类的加载过程吧! JVM的类的加载过程分为五个阶段:加载、验证、准备、解析、初始化 加载 加载阶段就是将编译好的的class文件通过字节流的方式从硬盘或者通过网络加载到JVM虚拟机当中来。

    2024年02月09日
    浏览(15)
  • JVM(类的加载与ClassLoader、双亲委派机制)

    类在内存中完整的生命周期: 加载--使用--卸载 。其中加载过程又分为: 装载、链接、初始化 三个阶段。 当程序主动使用某个类时,如果该类还未被加载到内存中,系统会通过加载、链接、初始化三个步骤来对该类进行初始化。如果没有意外,JVM将会连续完成这三个步骤,

    2024年02月03日
    浏览(13)
  • 【Java语言面向对象】(1)面向过程编程

    人机猜拳的第一版(下方是程序源码) 人机猜拳(面向过程版本) 三部分组成 初始化 游戏开始 游戏数据统计 逐步完成,并阶段测试。 面向过程整体的思路:做一件事,分为多个步骤,每个步骤之间是有序的,最后按序完成。 面向过程的优缺点: 优点:符合人类思维,简

    2023年04月09日
    浏览(19)
  • HarmonyOS/OpenHarmony应用开发-ArkTS语言渲染控制LazyForEach数据懒加载

    LazyForEach从提供的数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。当LazyForEach在滚动容器中使用了,框架会根据滚动容器可视区域按需创建组件,当组件划出可视区域外时,框架会进行组件销毁回收以降低内存占用。 一、接口描述 二、IDataSource类型说明 三、

    2024年02月11日
    浏览(16)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包