Mxililove 发表于 2022-9-2 20:23

求解关于Java常量在类加载过程中具体初始化位置

本帖最后由 Mxililove 于 2022-9-2 23:10 编辑

大佬们,我在看老韩的视频讲到反射的时候有提到:
如果一个**常量**在类里被定义的时候是在**类加载的连接过程**中直接把1赋值给n
```java
static final int n = 1;
```
**问题:**如果现在我在定义常量时不直接定义,而是在静态代码块里定义,那这个赋值过程是在类加载的连接过程中进行的还是在类初始化的时候进行的?
```java
static final int n;
static {
    n = 1;
}
```
-----------
下面是韩老师画的类加载的几个阶段:
![](https://images-1257699643.cos.ap-guangzhou.myqcloud.com/202209022245812.png)
如果静态成员变量我们赋值了初始值比方说`static int n = 1;`那么:
1、`n`会在连接的准备阶段先赋上默认值`0`
2、到了初始化阶段再赋值为`1`
而常量`static final int n = 1;`则是直接在准备阶段赋值为1。
初始化又是将静态代码块收集起来执行,所以就比较疑惑,如果常量的赋值是在静态代码块中的话,那么这个常量的赋值过程是在类加载的哪个阶段进行的呢?

Bakura 发表于 2022-9-2 20:51

static 不是随着类的加载而加载的吗?

萋小磊 发表于 2022-9-2 21:07

有点类似于惰性, 当这个Class被加载的时候触发,
如果没使用到或者用反射调用就在调用的那之前加载

不夏流年 发表于 2022-9-2 21:14

本帖最后由 不夏流年 于 2022-9-2 21:16 编辑

准备阶段赋默认值,int默认值为0.所以此时n为0

初始化时将初始值1赋值给n

不推荐在此求助!

s1986q 发表于 2022-9-2 21:21

常量在类里被定义,
在编译class时,以确定。

Vvvvvoid 发表于 2022-9-2 22:05

static 修饰的都是在类加载器时完成的

类初始化 都是实力对象 , 不是 静态对象

Mxililove 发表于 2022-9-2 22:54

Bakura 发表于 2022-9-2 20:51
static 不是随着类的加载而加载的吗?

这是韩老师画的类加载图,在第一次引用类的时候,静态成员变量会在连接的准备阶段先初始化为默认值,然后再把初始值赋给变量,但是final修饰的常量赋值一次之后就不能再变更了,韩老师说常量是直接在连接的准备阶段赋初始值的。
我疑惑的就是,如果我初始值是写到静态代码块里去,也是在这一步赋值吗?https://images-1257699643.cos.ap-guangzhou.myqcloud.com/202209022245812.png

千城忆梦 发表于 2022-9-3 00:37

程序的执行过程(若有的话):

    - 超类的static块
    - 派生类的static块
    - 超类的构造方法
    - 派生类的构造方法

zzh2022 发表于 2022-9-3 01:48

韩老师永远的神,就是教程太长了,要看n多周期

unmask 发表于 2022-9-3 10:42

根据我的理解,2种方式在编译优化后生成的字节码应该是一致的,都是静态数据,加载完后都会放置到堆内静态区
页: [1]
查看完整版本: 求解关于Java常量在类加载过程中具体初始化位置