java - 当我们第一次使用一个类时,是否总是执行静态代码?

标签 java static jvm final

我们的应用程序使用的初始化代码取决于静态代码的执行顺序,我想知道这个顺序是否会在所有 JVM 中保持一致。

这是我的意思的示例:


public class Main {

    static String staticVar = "init_value";

    public static void main(String[] args) {

        System.out.println(A.staticVar);
        staticVar = "mainValue";
        System.out.println(A.staticVar);
    }
}

public class A {
    static String staticVar = Main.staticVar;
}

将给予:

init_value
init_value

and


public class Main {

    static String staticVar = "init_value";

    public static void main(String[] args) {

        // System.out.println(A.staticVar);
        staticVar = "mainValue";
        System.out.println(A.staticVar);
    }
}

public class A {
    static String staticVar = Main.staticVar;
}

将给出(在我的环境中):

mainValue

总而言之,在所有 JVM 中,当我们第一次使用一个类时,是否总是执行静态代码?

最佳答案

编辑:尽管有以下所有保证,但如果您正在考虑依赖此类东西,我会努力重构您的代码,以免它突然出现。虽然它 保证可以正常工作,但它也可能使您的代码变得非常脆弱。静态初始化程序被“不可见地”调用这一事实使它们相对难以推理和调试。


是的,这是由语言规范保证的。来自 section 8.7规范的:

Any static initializers declared in a class are executed when the class is initialized and, together with any field initializers (§8.3.2) for class variables, may be used to initialize the class variables of the class (§12.4).

StaticInitializer: static Block

It is a compile-time error for a static initializer to be able to complete abruptly (§14.1, §15.6) with a checked exception (§11.2). It is a compile-time error if a static initializer cannot complete normally (§14.21).

The static initializers and class variable initializers are executed in textual order.

来自section 12.4 :

Initialization of a class consists of executing its static initializers and the initializers for static fields declared in the class. Initialization of an interface consists of executing the initializers for fields declared in the interface.

Before a class is initialized, its direct superclass must be initialized, but interfaces implemented by the class need not be initialized. Similarly, the superinterfaces of an interface need not be initialized before the interface is initialized.

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.
  • T is a class and 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).
  • T is a top-level class, and an assert statement (§14.10) lexically nested

关于java - 当我们第一次使用一个类时,是否总是执行静态代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3196016/

相关文章:

java - 如何测试JavaMailSender?

java - 我无法限制 Java 堆大小

java - 使用 RSA 解密字符串会在开头返回额外的零

android - Kotlin 静态函数 : companion object, @JvmStatic @JvmField

java - 是否可以在运行时禁用 `-XX:+PrintCompilation` 和 `-verbose:gc"`?

java - javac 是否优化 "foo".length()?

java - 如何在 JLabel 中循环元素的文本?

java - 为什么下面的代码片段没有给出编译时错误?

c++ - 在函数调用中更新静态成员会导致崩溃

java - 尝试在 eclipes 中编译 JAVA 1.7.0 的 "Original"库源代码时出错