java Singleton模式的静态初始化与枚举方法

cyej8jka  于 2023-02-18  发布在  Java
关注(0)|答案(2)|浏览(183)

我正在从Head First设计模式书中学习单例设计模式。
他们给出了一种使用静态初始化的方法,静态初始化是在类加载的时候完成的,这种方法的问题是即使我们没有使用示例(在类加载的时候),它也会创建示例,这意味着它会做eager initialization

public enum Singleton {
    private static Singleton uniqueInstance = new Singleton();

    // Other useful fields here (can be static or non-static)

    private Singleton() {}
    public static Singleton getInstance() {
        return uniqueInstance;
    }

    // Other useful methods here (can be static or non-static)
}

他们给出了另一种使用枚举的方法。

public enum Singleton {
    UNIQUE_INSTANCE;
 
    // other useful fields here (can be static or non-static)

    public static Singleton getInstance() {
        return UNIQUE_INSTANCE;
    }

    // other useful methods here (can be static or non-static)
}

我想知道上述方法在创建对象的时间方面有什么区别(在这两种情况下,我们在应用程序中使用该对象,以及在整个应用程序中不使用该对象)。
换句话说,我想知道枚举方法是否也能处理eager initialization

eeq64g8w

eeq64g8w1#

使用枚举时,单个常量是公共的,不需要为它添加getter。
就我而言,只有在需要枚举的优点时才使用它。虽然没有那么多优点,因为比较和切换与单个示例无关。有一个优点我可以想到(如果你需要的话):枚举是可序列化的。让序列化对非枚举单例有效并非易事;你需要使用readResolve(也可能是writeReplace)来确保当从流中读取序列化的单例值时,不会返回新的示例。2尽管仍然会创建一个示例,但它会被丢弃。3当使用枚举时,你可以免费获得序列化。

pokxtpni

pokxtpni2#

👉 枚举对象在enum类加载时示例化。
因此,是的,您可以将其视为“急切初始化”。
使用enum在Java中定义SingletonDr. Joshua Bloch在他的名著 Effective Java 中推荐的方法。

相关问题