如果我们将一个类实现为单例,请执行以下操作

class Single
{
  private Single singleton;

  public static Single getInstance()
  {
    if(null == singleton)
    {
      singleton = new Single();
    }
    return singleton;
  }

  //then we make the constructor private
  private Single()
  {
  }
}


考虑到上述情况,是否最好重写clone()以避免类的多个实例?

最佳答案

clone()界面中没有Cloneable方法。作为@Ivan points out,如果您的类未实现Cloneable,则calling Single#clone() will throw a CloneNotSupportedException



话虽这么说,克隆是如今在编写良好的Java中很少发生的事情。正如乔什·布洛赫(Josh Bloch)在《有效的Java》中写的,第11项:


Cloneable接口旨在用作对象的混合接口(项目18)
宣传他们允许克隆。不幸的是,它不能达到这个目的。它的
主要缺陷是它缺少clone方法,并且Object的clone方法受到保护。
您不能不借助反射(第53项)而调用clone
对象上的方法仅因为它实现了Cloneable。甚至反光
调用可能会失败,因为无法保证对象具有可访问性
clone方法。尽管存在此缺陷和其他缺陷,该设施仍在广泛使用,因此值得
理解。


...基本上,人们不/不应该使用clone()。这是一个设计不良的接口,如果您希望对象是可克隆的,最好提供一个复制构造函数或复制工厂方法(从项目11中窃取的代码):

public Yum(Yum yum); // copy constructor
public static Yum newInstance(Yum yum); // copy factory




在我谈论有效Java时,有一种更好的方式来编写单例,假设您确实需要一个单例(如果这么大!)。


从1.5版开始,存在第三种实现单例的方法。只是
用一个元素创建一个枚举类型:


// Enum singleton - the preferred approach
public enum Elvis {
    INSTANCE;
    public void leaveTheBuilding() { ... }
}


该方法在功能上等同于公共领域方法,除了它
更简洁,免费提供序列化机制,并提供
铁定的保证即使面对复杂的情况也不会多重实例化
序列化或反射攻击。虽然这种方法尚未广泛
采用单元素枚举类型是实现单例的最佳方法。

关于java - 实现单例模式,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4927429/

10-13 05:44