实现单例模式
如果我们将一个类实现为单例,我们会执行以下操作
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()以防止该类的多个实例是一个好主意吗?
If we are implementing a class as a singleton, we do the following
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()
{
}
}
Considering the above, wiil it be a good idea to override clone() as well to prevent multiple instances of the class?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
Cloneable
接口中没有clone()
方法。正如 @Ivan 指出的,如果你的类没有实现Cloneable 然后 调用
Single#clone()
将抛出CloneNotSupportedException
。也就是说,克隆现在在编写良好的 Java 中很少发生。正如 Josh Bloch 在《Effective Java》第 11 条中所写:
...基本上,人们不会/不应该使用
clone()
。这是一个设计得很糟糕的接口,如果你希望你的对象是可克隆的,最好提供一个复制构造函数或复制工厂方法(从条款 11 中窃取的代码):当我谈论 Effective Java,有一种更好的方法来编写单例,假设您确实需要一个(这是一个很大的假设!)。
这种方法在功能上等同于公共字段方法,不同之处在于它
更加简洁,免费提供序列化机制,并提供
即使面对复杂的情况,也能坚决保证防止多重实例化
序列化或反射攻击。虽然这种方法尚未广泛推广
采用,单元素枚举类型是实现单例的最佳方式。
There is no
clone()
method in theCloneable
interface. As @Ivan points out, if your class does not implementCloneable
then callingSingle#clone()
will throw aCloneNotSupportedException
.That said, cloning is something that happens infrequently in well-written Java these days. As Josh Bloch writes in Effective Java, Item 11:
...basically, people don't/shouldn't use
clone()
. It's a poorly designed interface, and if you want your objects to be cloneable, it's better to provide a copy constructor or copy factory method (code stolen from Item 11):And while I'm talking about Effective Java, there's a better way to write a singleton, assuming that you really do need one (which is a big if!).
This approach is functionally equivalent to the public field approach, except that it
is more concise, provides the serialization machinery for free, and provides an
ironclad guarantee against multiple instantiation, even in the face of sophisticated
serialization or reflection attacks. While this approach has yet to be widely
adopted, a single-element enum type is the best way to implement a singleton.
如果你不实现 clonable 它就不应该是可克隆的。
附注
更干净的java单是:
if you dont implement clonable it should not be clonable.
p.s.
a cleaner java single is:
对单例对象的任何
clone()
调用都将失败,如下所述:http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#clone%28 %29
如果该类不是
Cloneable
(未指定实现 Cloneable
),则会引发CloneNotSupportedException
错误。所以不,没有必要。代码越少越好:)
Any calls to
clone()
on your singleton object will fail, as explained here:http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#clone%28%29
If the class is not
Cloneable
(does not specifyimplements Cloneable
), aCloneNotSupportedException
error will be thrown.So no, it's not necessary. And less code is goooood :)
默认情况下,clone() 方法被标记为受保护,但如果您的类扩展了另一个支持克隆的类,则可能会违反单例的设计原则。
在这种情况下,是的,这是一个好主意:
By default, the clone() method is marked as protected, but if your class extends another class that does support cloning, it is possible to violate the design principles of the singleton.
In that case, yes this is a good idea:
正如他所说,没有什么可以覆盖的。
一般来说,关于您的单例实现 - 它有很多很多缺陷(除了代码示例中的明显错误)。考虑多线程、反射、序列化/反序列化。将其作为具有 1 个常量的枚举对您来说会更容易,因为您不必编写任何代码来强制执行该属性。
看看这个对另一个问题的回答(忽略有关
hashCode()
的部分)。还要注意评论。As he said, there is nothing to override.
Regarding your singleton implementation in general - there are many, many flaws with it (apart from the obvious mistakes in the code sample). Think about multithreading, reflection, serialization/deserialization. Making it as an enum with 1 constant will be much easier on your side since you won't have to write any code to enforce the property.
Take a look at this answer to another question (disregard the part about
hashCode()
). Also take note of the comments.