java - 类加载与初始化 : Java static final variable

标签 java memory jvm classloading in-class-initialization

<分区>

例子.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 即常量 值。但是 Example 类还没有加载。 但是,当我将输入作为 2 时,只有这样 Example 类被加载到 JVM 中,如详细输出所示,然后执行 Example 中的静态 block ,并初始化 j 的值,然后打印。

我的查询是:如果对于输入 1,即当另一个类 Example 的静态最终(常量)值被请求时class Use,那么如果 class Example 在此之前从未加载到 JVM 中,那么从哪里获取常量值? static final i 何时以及如何初始化并存储到 JVM 内存中?

最佳答案

根据Java language specification section 12.4.1 (强调):

A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

  • T is a class and an instance of T is created.

  • A static method declared by T is invoked.

  • A static field declared by T is assigned.

  • A static field declared by T is used and the field is not a constant variable (§4.12.4).

A constant variable是用 constant expression 初始化的最终变量.在您的代码中,Example.i 是一个常量变量,因此不会导致类被加载。

那么如果类没有加载,值从哪里来呢?

语言规范要求编译器内联它的值。来自 binary compatibility 13.1 的部分:

  1. A reference to a field that is a constant variable (§4.12.4) must be resolved at compile time to the value V denoted by the constant variable's initializer.

    If such a field is static, then no reference to the field should be present in the code in a binary file, including the class or interface which declared the field. Such a field must always appear to have been initialized (§12.4.2); the default initial value for the field (if different than V) must never be observed.

关于java - 类加载与初始化 : Java static final variable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63534066/

相关文章:

ios - 为什么在 ARC 中发送消息会导致保留周期警告,但属性集不会?

c - .o 文件中的内存共享

java - 为什么 OpenJDK 将私有(private)方法放入 vtable 中?

java - JPA 的 EntityManager 应该是 RequestScoped 吗?

Java正则表达式来验证和提取一些值

java - 空闲内存是否在 Android 设备上消耗更少的电量?

java.lang.VerifyError : Stack map does not match the one at exception handler

java - Android Studio 启动 - MaxJavaStackTraceDepth = -1 超出允许范围 - 错误

java - 将查看寻呼机详细信息转换为 json 时出错

java - 编写高效且无冗余的测试