【发布时间】:2020-06-08 21:36:14
【问题描述】:
假设我有以下项目结构:
Inst.java
import java.lang.instrument.Instrumentation;
final public class Inst {
private static Instrumentation instrumentation;
public static void premain(String args, Instrumentation inst) {
instrumentation = inst;
}
public static long sizeof(Object o) {
return instrumentation.getObjectSize(o);
}
}
常量.java
public class Constants {
public static final int MAX_LENGTH = 10;
}
SomeClass.java
public class SomeClass {
private int myVar;
public SomeClass(final int myVar) {
this.myVar = myVar;
}
public static class StaticClass {
private static final int SOME_VAR = 1;
}
}
Main.java
public class Main {
public static void main(String [] args) {
int init = Constants.MAX_LENGTH;
SomeClass clazz = new SomeClass(init);
}
}
Oracle 文档声明如下:
Java 虚拟机 (JVM) 初始化后,每个 premain 方法将按照代理指定的顺序调用,然后调用真正的应用程序 main 方法。
在我看来,这意味着 premain 方法在 JVM 初始化后立即调用,因此首先初始化 Inst(在本例中)。
此外,static 在类加载时被初始化(据我所知),或更一般地,在类的第一次引用时被初始化。
所以这意味着,在这个例子中,初始化和执行顺序如下:
-
JVM初始化后调用
premain() -
main()被称为应用程序的入口点 -
Constants.MAX_LENGTH已初始化(在 main 中引用) -
StaticClass已初始化(由于正在创建外部类的实例) -
SomeClass的实例已创建
我上面的顺序正确吗?
【问题讨论】:
-
第一:Constants.MAX_LENGTH是一个常量表达式,which doesn't load the class。
-
对不起。你的问题不清楚。您是在编写“Java 编程语言代理”还是在编写常规 Java 程序?您如何运行问题中的代码?
-
第二:内部类没有以JLS§12.4.1描述的方式访问,所以没有初始化。
-
第三:您可以在您的类中添加
static {System.out.println("Foo is initialized"); },以查看它们何时加载。 -
@JohannesKuhn
Constants.MAX_LENGTH写在代码中不是最终的,所以它不是一个常数,即使它都是大写的。
标签: java static initialization