如果我们将一个类实现为单例,请执行以下操作
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/