私有类上的静态最终成员初始化

时间:2014-05-11 04:48:47

标签: java static initialization final

请考虑以下代码:

public final class Foo {
    private static final Random random = new Random();
    private Foo() {}
}

当初始化随机时,无法实例化此类?

2 个答案:

答案 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节,在这些情况下进行初始化:

  1. T是一个类,并创建了一个T实例。

  2. T是一个类,调用T声明的静态方法。

  3. 分配由T声明的静态字段。

  4. 使用T声明的静态字段,该字段不是常量变量(§4.12.4)。

  5. T是顶级类(第7.6节),并且执行在词典中嵌套在T(第8.1.3节)内的断言语句(第14.10节)。

    1. 不能发生,因为构造函数是私有的。 2.由于Foo没有静态方法,因此无法发生。 3.不能发生因为静态字段是私有的。 4.不能发生因为静态字段是私有的,所以不能使用。 5.因为没有断言陈述而不能发生。
  6. 所以我认为random不会被初始化,因为OP的代码就是这样(编辑:除非你使用反射)