请考虑以下代码:
public final class Foo {
private static final Random random = new Random();
private Foo() {}
}
当初始化随机时,无法实例化此类?
答案 0 :(得分:3)
在类初始化期间初始化静态字段,例如
...
Class.forName("test.Foo");
...
加载JVM后将初始化random
字段,不会创建任何Foo实例。为了测试它,我们可以像这样改变Foo
class Foo {
private static final Random random = new Random() {
{
System.out.println("random initialized");
}
};
...
答案 1 :(得分:2)
根据Java Language Specification section 12.4,在类初始化期间初始化静态成员和块。初始化类的精确时间以及执行此操作的步骤可以在链接中找到;通常,类在第一次以任何方式访问时都会加载/初始化,并且加载/初始化包括创建静态成员。
但是,如果只有Foo
,我不相信random
将被初始化,因为它无法实例化,其静态成员无法访问,也不能子类。根据JLS第12.4.1节,在这些情况下进行初始化:
T是一个类,并创建了一个T实例。
T是一个类,调用T声明的静态方法。
分配由T声明的静态字段。
使用T声明的静态字段,该字段不是常量变量(§4.12.4)。
T是顶级类(第7.6节),并且执行在词典中嵌套在T(第8.1.3节)内的断言语句(第14.10节)。
Foo
没有静态方法,因此无法发生。 3.不能发生因为静态字段是私有的。 4.不能发生因为静态字段是私有的,所以不能使用。 5.因为没有断言陈述而不能发生。所以我认为random
不会被初始化,因为OP的代码就是这样(编辑:除非你使用反射)