在编译时或运行时,Java 中的常量何时在内存中分配空间?

When exactly is the space allocated in memory for a constant in Java at compile-time or runtime?

提问人:elvis 提问时间:10/29/2023 更新时间:10/29/2023 访问量:43

问:

我正在学习 Java 常量,我想知道内存中为常量分配的空间究竟是什么时候。是在编译时还是在运行时?例如,我有一个这样的常量:

public static final int NUMBER = 5;

我知道,对于实例或类变量,空间是在运行时在内存中分配的,对于实例变量,空间是在创建对象时在内存中分配的,而对于类变量,空间是在加载类时分配的。但是,对于一个常数来说,发生了什么?我知道编译器在找到这个常量并用其值替换代码中所有位置的每个常量名称时会进行一些优化。但是,内存中为这个常量 NUMBER 分配的空间究竟是什么时候分配的呢?在编译时还是在运行时?

Java 常量运行时 最终 编译时

评论

0赞 user207421 10/29/2023
@Turing85 Java 中充满了常量,例如问题中的常量。字符串文字是另一个示例。类文件格式中有一个常量池。
0赞 Turing85 10/29/2023
@user207421呵呵。在 JLS 中挖了一点。你是对的,有恒定的变量......
0赞 user207421 10/29/2023
这个问题的答案是“两者兼而有之”。编译器根据大小在堆栈帧和常量池中分配空间,JVM 分配与这些大小相对应的内存。
0赞 Sweeper 10/29/2023
“对于类变量,加载类的时刻是”您刚刚回答了自己的问题。您甚至发现编译器可以内联常量。你还想得到什么回答?
0赞 elvis 10/29/2023
@Sweeper正如我所说“对于类变量,那一刻是加载类的时候”,但我想确定为像 NUMBER(或编译时常量)这样的常量分配内存的那一刻,因为我问了 Chatgpt,它说“Java 中编译时常量的内存是在编译过程中分配的,并且是类文件中字节码的一部分。

答:

0赞 etienneZink 10/29/2023 #1

内存分配永远不会在编译时发生,因为编译只生成字节码,并且永远不会为运行时分配任何内存。编译时的内存分配将导致内存泄漏。你永远不知道什么时候释放内存(停止问题/我会再次使用它吗?也许你的意思是:在编译时,编译器用“常量”的文字/值替换(如你所说)你的标识符。