如何确保 JVM 中只有一个类的实例?

2022-09-02 00:12:30

我正在开发一个设计模式,我想确保这里只是Java虚拟机中一个类的一个实例,通过一个点汇集对某些资源的所有请求,但我不知道这是否可能。

我只能想出一种方法来计算一个类的实例,并在创建第一个实例后销毁所有实例。

这是正确的方法吗?如果没有,还有其他方法吗?


答案 1

使用单例模式。最简单的实现由 a 和 a 组成,用于保存其结果,以及名称类似于 的访问器方法。private constructorfieldstaticgetInstance()

私有字段可以从静态初始值设定项块中分配,或者更简单地说,使用初始值设定项进行分配。然后,该方法(必须是公共的)只需返回此实例,getInstance()

public class Singleton {
    private static Singleton instance;

    /**
     * A private Constructor prevents any other class from
     * instantiating.
     */
    private Singleton() {
        // nothing to do this time
    }

    /**
     * The Static initializer constructs the instance at class
     * loading time; this is to simulate a more involved
     * construction process (it it were really simple, you'd just
     * use an initializer)
     */
    static {
        instance = new Singleton();
    }

    /** Static 'instance' method */
    public static Singleton getInstance() {
        return instance;
    }

    // other methods protected by singleton-ness would be here...
    /** A simple demo method */
    public String demoMethod() {
        return "demo";
    }
}

请注意,在方法中使用“延迟计算”的方法(在设计模式中提倡)在Java中不是必需的,因为Java已经使用了“延迟加载”。除非调用单例类,否则可能不会加载它,因此,在需要它之前,尝试推迟单例构造是没有意义的,方法是测试单例变量并在那里创建单例。getInstance()getInstance()getInstance()null

使用这个类同样简单:只需获取并保留引用,然后调用其上的方法:

public class SingletonDemo {
    public static void main(String[] args) {
        Singleton tmp = Singleton.getInstance();
        tmp.demoMethod();
    }
}

一些评论家认为,单例还应该提供一个公共的最终方法,只是抛出一个异常,以避免“作弊”的子类和单例。但是,很明显,只有私有构造函数的类不能被子类化,因此这种偏执似乎没有必要。clone()clone()


答案 2

这就是众所周知的单例模式:您可以按如下方式实现它:

public class SingletonClass {

    //this field contains the single instance every initialized.
    private static final instance = new SingletonClass();

    //constructor *must* be private, otherwise other classes can make an instance as well
    private SingletonClass () {
        //initialize
    }

    //this is the method to obtain the single instance
    public static SingletonClass getInstance () {
        return instance;
    }

}

然后,您可以使用以下命令调用该实例(就像构造非单例一样):

SingletonClass.getInstance();

但在文学作品中,辛格尔顿通常被认为是一个糟糕的设计理念。当然,这总是取决于情况,但大多数程序员建议不要这样做。只是说出来,不要向信使开枪...


推荐