这个问题在这里已经有答案了:
未调用静态块(2个答案)
5个月前关门了。
示例.java
public class Example {
static final int i = 10;
static int j = 20;
static {
System.out.println("Example class loaded and initialized");
}
}
使用.java
import java.util.Scanner;
public class Use {
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
int ch = 1;
while(ch != 0) {
System.out.print("Enter choice: ");
ch = sc.nextInt();
if (ch == 1) {
System.out.println("Example's i = " + Example.i);
} else if(ch == 2){
System.out.println("Example's j = " + Example.j);
}
}
}
}
当我和 java -verbose:class Use
,并以 1
则输出为 10
i、 e常数 i
价值观。但是 Example
类尚未加载。但是,当我以 2
,只有那时 Example
类被加载到jvm中,如详细输出所示,然后执行示例中的静态块,并且 j
的值初始化,然后打印。
我的问题是:如果输入 1
i、 当类的静态最终(常量)值 Example
在另一个类中被请求 Use
,那么如果类 Example
在此之前从未加载到jvm中?静态决赛是什么时候,怎样进行的 i
初始化并存储到jvm内存中?
1条答案
按热度按时间gab6jxml1#
根据java语言规范第12.4.1节(增加重点):
类或接口类型t将在第一次出现以下任一情况之前立即初始化:
t是一个类,创建了一个t的示例。
调用由t声明的静态方法。
分配一个由t声明的静态字段。
使用由t声明的静态字段,并且该字段不是常量变量(§4.12.4).
常量变量是用常量表达式初始化的最终变量。在你的代码里,
Example.i
是一个常量变量,因此不会导致类被加载。因此,如果类没有加载,那么com值从何而来?
语言规范要求编译器内联其值。从二进制兼容性13.1节:
对作为常量变量的字段的引用(§4.12.4)必须在编译时解析为常量变量的初始值表示的值v。
如果这样的字段是静态的,那么二进制文件中的代码中不应存在对该字段的引用,包括声明该字段的类或接口。这样的字段必须始终显示为已初始化(§12.4.2); 决不能遵守字段的默认初始值(如果与v不同)。