内存类加载与初始化:java静态final变量

68bkxrlz  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(352)

这个问题在这里已经有答案了

未调用静态块(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内存中?

gab6jxml

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不同)。

相关问题