• 第九章、类的生命周期


    1、Java虚拟机及程序的生命周期

    【定义】: Java虚拟机进程从启动到终止的过程,称为Java虚拟机的生命周期。

    【结束场景】:

    • 程序正常执行结束。
    • 程序在执行过程中由于错误或异常而异常终止。
    • 执行了System.exit()方法。
    • 由于操作系统出错导致Java虚拟机异常终止。

    2、类的加载、连接和初始化

    【图示】:
    在这里插入图片描述

    1、类的加载

    【作用】: 把类的.class文件中的二进制数据读入到内存中,把它存放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。

    【图解】:
    在这里插入图片描述

    2、类的验证

    【定义】: 连接就是把已经读入到内存的类的二进制数据合并到虚拟机的运行时环境中去。

    【验证的内容】:

    • 类文件的结构检查:确保类文件遵从Java类文件的固定格式。
    • 语义检查:确保类本身符合Java语言的语法规定,比如验证final类型的类没有子类,以及final类型的方法没有被覆盖。
    • 字节码验证:确保字节码流可以被Java虚拟机安全地执行。
    • 二进制兼容的验证:确保相互引用的类之间协调一致。

    3、类的准备

    【定义】: Java虚拟机为类的静态变量分配内存,并设置默认的初始值。

    4、类的解析

    【定义】: Java虚拟机会把类的二进制数据中的符号引用替换为直接引用。

    5、类的初始化

    【定义】: Java虚拟机执行类的初始化语句,为类的静态变量赋予初始值。

    【静态变量初始化的两种途径】:

    • 在静态变量的声明处进行初始化。
    • 在静态代码块中进行初始化。

    【步骤】:

    • 假如这个类还没有被加载和连接,那就先进行加载和连接。
    • 如果类存在直接的父类,并且这个父类还没有被初始化,那么就先初始化直接的父类。
    • 如果类中存在初始化语句,那么就依次执行这些初始化语句。

    6、类的初始化的时机

    • 创建类的实例。(用new语句,反射、克隆、反序列化)
    • 调用类的静态方法。
    • 访问某个类或接口的静态变量,或者对该静态变量赋值。
    • 调用JavaAPI中的某些反射方法。
    • 初始化一个类的子类。
    • Java虚拟机启动时被标明为启动类的类。

    3、类加载器

    【分类】:

    • 根类加载器:该加载器没有父加载器。它负责加载虚拟机的核心类库。
    • 扩展类加载器:它的父加载器为根类加载器。
    • 系统(System)类加载器:也称为应用类加载器,它的父加载器为扩展类加载器。它从classpath环境变量或者系统属性 java.class.path所指定的目录中加载类,它是用户自定义的类加载器的默认父加载器。

    【图解关系】:
    在这里插入图片描述

    1、类加载的父亲委托机制

    【解释】: 在父亲委托机制中,各个加载器按照父子关系形成了树形结构,除了根类加载器之外,其余的类都有且只有一个父类加载器。

    【图解】:
    在这里插入图片描述
    【分析】:

    • 如图所示loader2的父亲是loader1,loader1的父亲是系统类加载器,依此类推。
    • 假设Java程序要求loader2加载Sample类,loader2首先会在自己的命名空间中查找Simple类是否被加载,如果已经加载就直接返回该类的Class对象的引用。
    • 如果Sample类还没有被加载,loader2首先请求loader1代为加载,loader1再请求系统类加载器代为加载,系统类加载器再请求扩展类加载器代为加载,扩展类加载器再请求根类加载器代为加载。
    • 若根类加载器和扩展类加载器都不能加载,则系统类加载器尝试加载,若能加载成功,则将Sample类所对应的Class对象的引用返回给loader1,loader1再将引用返回给loader2,从而成功地将Sample类加载进虚拟机。
    • 若系统类加载器不能加载Sample类,则loader1尝试加载Sample类,若loader1也不能成功加载,则loader2尝试加载。
    • 若所有的父加载器及loader2本身都不能加载,则抛出ClassNotFoundException异常。

    2、创建用户自定义类加载器

    【方法】: 要创建用户自己的类加载器,只需扩展java.lang.ClassLoader类,然后覆盖它的findClass(String name)方法,该方法根据参数指定的类的名字,返回对应的Class对象的引用。

    3、URLClassLoader类

    【解释】: 在JDK的java.net包中,提供了一个功能比较强大的URLClassLoader类,它扩展了ClassLoader类。它不仅能从本地文件系统中加载类,还可以从网上下载类。Java程序可直接用URLClassLoader类作为用户自定义的类加载器。

    4、类的卸载

    【解释】: 当类被加载、连接和初始化后,它的生命周期就开始了。当代表类的Class对象不再被引用,即不可触及时,那么Class对象就会结束生命周期,Sample类在方法区内的数据也会被卸载,从而结束类的生命周期。

  • 相关阅读:
    京津冀协同发展:北京·光子1号金融算力中心——智能科技新高地
    【进阶篇】使用 Redis 实现分布式缓存的全过程思考(一)
    0. linux-riscv内存管理120问大纲
    美创科技获通信网络安全服务能力评定(应急响应一级)认证!
    【LeetCode-中等题】78. 子集
    文件管理:文件存储空间管理
    脚本:python绘制七夕爱心
    公司金融试题及答案
    Object和Function是函数,函数都有一个prototype属性
    LeetCode使用JavaScript破解两数之和
  • 原文地址:https://blog.csdn.net/m0_37911124/article/details/126076555