我创建了一个包含以下内容的类:
static final
变量static
带有System.out.println()
语句的初始化程序 block
如果我从另一个类调用 static final
变量,static
block 不会执行。
据我所知,static
初始化程序 block 在类加载到内存中时执行。
在这种情况下,内存级别发生了什么?
类没有加载到内存中吗?如果不是,其他类从哪里获取final static
变量的地址?
情况 1: static
block 不执行
class Test2 {
static final int a = 20;
static {
System.out.println("one");
}
}
情况 2:static
block 执行
class Test2 {
static final int a;
static {
a = 20;
System.out.println("one");
}
}
输出
class Test {
public static void main(String[] args) {
System.out.println(Test2.a);
}
}
案例一:
20
案例 2:
one 20
那么在这两个层面上发生了什么?
最佳答案
我的猜测是您的字段是原始类型或 String
,并且使用编译时常量表达式进行了初始化。
对于用常量表达式初始化的静态最终字段(并且只有这样的字段)——任何引用该字段的代码都会将常量值嵌入其中,而不是通过会导致类初始化的静态字段。 “常量表达式”部分很重要。我们可以通过一个小型测试应用程序看到这一点:
class Fields {
public static final String CONSTANT = "Constant";
public static final String NON_CONSTANT = new String("Non-constant");
static {
System.out.println("Initializing");
}
}
public class Test {
public static void main(String arg[]) {
System.out.println(Fields.CONSTANT);
System.out.println(Fields.NON_CONSTANT);
}
}
输出是:
Constant
Initializing
Non-constant
访问常量字段不需要初始化,但访问非常量字段需要。使用非 final 字段会产生相同的效果:基本上,它不再算作常量。
有关“这是一个常量”的信息被嵌入到声明字段的类中。例如,使用 javap -c Fields
我们可以看到两个字段:
public static final java.lang.String CONSTANT;
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
ConstantValue: String Constant
public static final java.lang.String NON_CONSTANT;
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
请注意 CONSTANT
字段元数据的 ConstantValue
部分,它在 NON_CONSTANT
字段元数据中缺失。
参见 section 15.28 of the JLS有关什么构成常量表达式的更多信息。
Section 12.4.1 of the JLS指定类何时初始化:
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 (§7.6), and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.
(强调我的。)
关于java - 静态最终变量以及静态初始化程序 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18997197/