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

  • T是一个类,并且创建了T的一个实例

  • T是一个类,调用由T声明的静态方法

  • 分配了一个由T声明的静态字段

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

  • T是一个顶级类(§7.6),执行嵌套在T(§8.1.3)中的assert语句(§14.10)

  • 无法发生,因为构造函数是私有的。2.不能发生,因为
    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
    被初始化。