Java 私有类上的静态最终成员初始化
考虑以下代码:Java 私有类上的静态最终成员初始化,java,static,initialization,final,Java,Static,Initialization,Final,考虑以下代码: public final class Foo { private static final Random random = new Random(); private Foo() {} } 该类无法实例化,因此,在初始化random时?静态字段在类初始化期间初始化,例如此处 ... Class.forName("test.Foo"); ... 加载JVM后,将初始化random字段,不会创建任何Foo实例。为了测试它,我们可以像这样改变
public final class Foo {
private static final Random random = new Random();
private Foo() {}
}
该类无法实例化,因此,在初始化random时?静态字段在类初始化期间初始化,例如此处
...
Class.forName("test.Foo");
...
加载JVM后,将初始化random
字段,不会创建任何Foo实例。为了测试它,我们可以像这样改变Foo
class Foo {
private static final Random random = new Random() {
{
System.out.println("random initialized");
}
};
...
根据,静态成员和块的初始化在类初始化期间进行。在链接中可以找到类初始化的精确时间和步骤;通常,类在第一次以任何方式访问时都会被加载/初始化,加载/初始化包括静态成员的创建
然而,如果这就是Foo
的全部内容,我不相信random
会被初始化,因为它不能被实例化,它的静态成员不能被访问,它也不能被子类化。根据JLS第12.4.1节,在以下情况下进行初始化:
Foo
没有静态方法。3.无法发生,因为静态字段是私有的。4.无法发生,因为静态字段是私有的,因此无法使用。5.无法发生,因为没有assert语句所以我不认为
random
会被初始化,因为OP的代码就是所有的代码(编辑:除非使用反射)这会导致加载Foo的类对象,而不是Foo本身吗?好的,反射是有效的。但是除了使用它,没有一种方法。。。此外,forName()
显式初始化新对象。因此,从技术上讲,这仍然在创建一个新的Foo
。使用Class.forName(“test.Foo”,false,Class.Class.getClassLoader())
不会初始化Foo
Class.forName(“test.Foo”)
不会创建test.Foo
的新实例。我同意,我并没有说它会将上面的代码与public int getRandomInt(){return random.nextInt()}这样的getter一起使用
如果使用getter,则满足条件2,因此可以加载Foo
。但是OP发布的代码永远不会导致random
被初始化。