前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Class 对象在执行引擎中的初始化过程

Class 对象在执行引擎中的初始化过程

作者头像
老马的编程之旅
发布2022-06-22 15:58:26
发布2022-06-22 15:58:26
1.1K00
代码可运行
举报
文章被收录于专栏:深入理解Android深入理解Android
运行总次数:0
代码可运行

一个 class 文件被加载到内存中需要经过 3 大步:装载、链接、初始化。

装载 装载是指 Java 虚拟机查找 .class 文件并生成字节流,然后根据字节流创建 java.lang.Class 对象的过程。

链接 链接过程分为 3 步:验证、准备、解析。

验证: 初始化 这是 class 加载的最后一步,这一阶段是执行类构造器方法的过程,并真正初始化类变量。

1.文件格式检验:检验字节流是否符合 class 文件格式的规范,并且能被当前版本的虚拟机处理。

2.元数据检验:对字节码描述的信息进行语义分析,以保证其描述的内容符合 Java 语言规范的要求。

3.字节码检验:通过数据流和控制流分析,确定程序语义是合法、符合逻辑的。

4.符号引用检验:符号引用检验可以看作是对类自身以外(常量池中的各种符号引用)的信息进行匹配性校验。

准备: 准备是链接的第 2 步,这一阶段的主要目的是为类中的静态变量分配内存,并为其设置“0值”。比如:

代码语言:javascript
代码运行次数:0
复制
public static int value = 100;

在准备阶段,JVM 会为 value 分配内存,并将其设置为 0。而真正的值 100 是在初始化阶段设置。并且此阶段进行内存分配的仅包括类变量,而不包括实例变量(实例变量将会在对象实例化时随着对象一起分配在 Java 堆中)。

有一种情况比较特殊–静态常量,比如:

代码语言:javascript
代码运行次数:0
复制
public static final int value = 100;

以上代码会在准备阶段就为 value 分配内存,并设置为 100。

Java 中基本类型的默认”0值“如下:

基本类型(int、long、short、char、byte、boolean、float、double)的默认值为 0;

引用类型默认值是 null;

解析 解析是链接的最后一步,这一阶段的任务是把常量池中的符号引用转换为直接引用,也就是具体的内存地址。在这一阶段,JVM 会将常量池中的类、接口名、字段名、方法名等转换为具体的内存地址。

在 main 方法中通过 invokevirtual 指令调用了 print 方法,“Foo.print:()V"就是一个符号引用,当

main 方法执行到此处时,会将符号引用“Foo.print:()V”解析(resolve)成直接引用,可以将直接引用理解为方法真正的内存地址。

代码语言:javascript
代码运行次数:0
复制
对于符号引用和直接引用,可以将其与生活中的微信聊天进行类比,在微信好友列表中,保存的是好友的名称或者别名(也就是符号引用),当我们真正给某个好友发消息时,计算机(JVM)会根据好友的名称找到对象计算机的 IP 地址(直接引用)并成功将消息发送给这一地址。 

初始化 这是 class 加载的最后一步,这一阶段是执行类构造器方法的过程,并真正初始化类变量。比如:

代码语言:javascript
代码运行次数:0
复制
public static int value = 100;

在准备阶段 value 被分配内存并设置为 0,在初始化阶段 value 就会被设置为 100。

总结一下对象的初始化顺序如下:

静态变量/静态代码块 -> 普通代码块 -> 构造函数

  1. 父类静态变量和静态代码块;
  2. 子类静态变量和静态代码块;
  3. 父类普通成员变量和普通代码块;
  4. 父类的构造函数;
  5. 子类普通成员变量和普通代码块;
  6. 子类的构造函数。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-03-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档