iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > node.js >JDK15类的后半生:准备、解析、初始化、卸载过程是什么
  • 825
分享到

JDK15类的后半生:准备、解析、初始化、卸载过程是什么

2024-04-02 19:04:59 825人浏览 薄情痞子
摘要

这篇文章主要介绍“jdk15类的后半生:准备、解析、初始化、卸载过程是什么”,在日常操作中,相信很多人在JDK15类的后半生:准备、解析、初始化、卸载过程是什么问题上存在疑惑,小编查阅了各式资料,整理出简单

这篇文章主要介绍“jdk15类的后半生:准备、解析、初始化、卸载过程是什么”,在日常操作中,相信很多人在JDK15类的后半生:准备、解析、初始化、卸载过程是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JDK15类的后半生:准备、解析、初始化、卸载过程是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

准备

两个目标:

  • 为已在方法区中的类的 static变量 分配内存

  • 为 static变量 设置初始值,不同数据类型初始默认值如下:

JDK15类的后半生:准备、解析、初始化、卸载过程是什么

案例

public static final int value = 123;

准备阶段后 value 的值为 0,而非 123,初始化后才为 123。

但若是被final修饰,若有初始值,则在编译阶段就会将初始值存入constantValue属性中,在准备阶段就将constantValue的值赋给该字段(此处将value赋为123)。

解析

把常量池中的符号引用转换成直接引用。

  • 符号引用

一组无歧义的符号来描述所引用的目标,与JVM的实现无关

  • 直接引用

直接指向目标的指针、相对偏移量、或是能间接定位到目标的句柄,和JVM实现相关

主要针对:类、接口、字段、类方法、接口方法、方法类型、方法句柄、调用点限定符。

初始化

真正开始执行类中定义的Java程序代码(或是字节码)。

类的初始化就是为类的static变量赋初始值,初始化阶段就是执行类构造器的过程。

  • 若类尚未被加载和链接,就先执行之

  • 若类存在父类,且父类未被初始化,就先初始化父类

  • 若类中存在初始化语句,就依次执行这些语句

若是接口

  • 初始化一个类时,并不会先初始化它实现的接口

  • 初始化一个接口时,并不会初始化它的父接口。只有当程序首次使用接口里的变量或调用接口方法时,才会导致接口的初始化

调用Classloader类的loadClass方法来装载一个类,并不会初始化这个类,不属于对类的主动使用

clinit()方法由编译器自动产生,收集类中static代码块中的类变量赋值语句和类中static变量的赋值语句:

在准备阶段,类中static变量已完成默认初始化

而在初始化阶段,clinit()方法对static变量进行显式初始化

类的初始化时机

Java程序对类的使用方式分为:

  • 主动使用

  • 被动使用

JVM必须在每个类或接口“首次主动使用”时才初始化它们,被动使用类不会导致类的初始化。

主动使用的场景

  • 创建类实例

  • 访问某个类或接口的静态变量 如果是 final 常量,而常量在编译阶段就会在常量池,没有引用到定义该常量的类,因此不会触发定义该常量类的初始化

  • 调用类的静态方法

  • 反射某个类

  • 初始化某个类的子类,而父类还没有初始化

  • JVM启动的时候运行的主类(等于第三条)

  • 定义了 default 方法的接口,当接口实现类初始化时

FAQ

  • clinit()方法是IDE自动收集类中所有类变量的赋值动作和static语句块中的语句合并产生的,IDE收集的顺序是由语句在源文件中出现的顺序所决定

  • static代码块只能访问到出现在static代码块之前的变量,定义在它之后的变量,在前面的static语句块可赋值,但不能访问

public class Test {     static {         i = 0;         System.out.println(i); //编译失败:"非法向前引用"     }     static int i = 1; }
  • 实例构造器init()需显式调用父类构造器,而类的clinit()无需调用父类的类构造器。JVM会确保子类的clinit()方法执行前,已执行完毕父类的clinit()。

  • 因此在JVM中第一个被执行的clinit()方法的类肯定是java.lang.Object。

  • 若一个类/接口无static代码块,也无 static成员变量的赋值操作,则编译器不会为此类生成clinit()方法。

  • 接口也需通过clinit()方法为接口中定义的static成员变量显式初始化。

  • 接口中不能使用static代码块,但仍有变量初始化的赋值操作,因此接口与类一样都会生成clinit()方法。区别在于:执行接口的clinit()方法无需先执行父接口的clinit()方法,只有当父接口中的static成员变量被使用到时才会执行父接口的clinit()方法。

  • JVM会保证在多线程环境中一个类的clinit()方法被正确加同步。当多条线程同时初始化一个类时,只会有一个线程去执行该类的clinit()方法,其它线程都被阻塞等待,直到活动线程执行clinit()方法完。

其他线程虽会被阻塞,只要有一个clinit()方法执行完,其它线程唤醒后不会再进入clinit()方法。同一个类加载器下,一个类型只会初始化一次。

类的卸载

当代表一个类的Class对象不再被引用,那么Class对象的生命周期就结束了,对应的在方法区中的数据也会被卸载。Jvm自带的类加载器装载的类,是不会卸载的,由用户自定义的类加载器加载的类是可以卸载的。

到此,关于“JDK15类的后半生:准备、解析、初始化、卸载过程是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: JDK15类的后半生:准备、解析、初始化、卸载过程是什么

本文链接: https://www.lsjlt.com/news/83912.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JDK15类的后半生:准备、解析、初始化、卸载过程是什么
    这篇文章主要介绍“JDK15类的后半生:准备、解析、初始化、卸载过程是什么”,在日常操作中,相信很多人在JDK15类的后半生:准备、解析、初始化、卸载过程是什么问题上存在疑惑,小编查阅了各式资料,整理出简单...
    99+
    2024-04-02
  • Java类的初始化过程是什么
    Java类的初始化过程包括以下几个步骤: 加载类:当程序中使用到某个类时,Java虚拟机会先通过类加载器将该类的字节码文件加载到...
    99+
    2023-10-26
    java
  • Spring的Bean初始化过程和生命周期是什么
    本篇内容介绍了“Spring的Bean初始化过程和生命周期是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、Spring创建bean的...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作