为了防止Singleton被反射破坏,一种方法是在私有构造函数中引发异常,如下代码所示:

public final class Foo {

    private static final Foo INSTANCE = new Foo();

    private Foo() {
        if (INSTANCE != null) {
            throw new IllegalStateException("Already instantiated");
        }
    }

    public static Foo getInstance() {
        return INSTANCE;
    }
}


上面是一个标准代码,但是我在想这是线程安全的吗?如果有多个线程尝试同时使用反射来创建实例[即在将类加载到主内存中之前,这意味着instance将为null,然后它们将成功吗?

最佳答案

在加载类之前,不能访问其静态成员(无论是直接访问还是通过反射访问)。静态最终成员将在加载过程中初始化(step 9 of the JLS description)。

因此,在您的情况下,线程无法执行以下操作:


正确构建之前,请参见INSTANCE
看到INSTANCE为空(除非第一次调用new Foo()引发异常)
初始化第二个实例(除非代码依赖于a different class loader

关于java - Singleton:在构造函数中引发异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16777075/

10-11 22:30
查看更多