Java:懒惰加载Singleton和reflection攻击?

如果我通过holder idiom或double checked lock实现Singleton,而不是调用’getInstance()’,使用reflection实例化它,然后在其上调用’getInstance()’,这将创建两个实例,打破模式。

所以我在类中添加一个静态’counter’成员,在类的私有构造函数中递增它,如果它超过’1’则抛出exception。 但在这种情况下,如果我首先通过reflection进行实例化,那么没有其他人能够在不抛出exception的情况下调用’getInstance()’。

那么我如何懒惰加载Singleton但却阻止它受到这次攻击呢? (我知道’Enum’模式,但有些人觉得它实际上是一个黑客。检查对这个接受的答案的评论: 这个Singleton是否对序列化和reflection攻击都有抵抗?顺便说一句,我的问题是不同的)。

编辑:我认为在DCL的情况下,通过使用静态计数器字段,基于类的同步构造函数并将“this”分配给静态成员,可以防止它。 但是,不确定如何在持有人成语的情况下防止它。

我个人坚持使用枚举,但也有初始化按需持有人(IODH)习语

static class SingletonHolder { static Singleton instance = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.instance; } 

这出现在Effective Java(第48项)中,但我第一次从疯狂的鲍勃的post中听到它

http://blog.crazybob.org/2007/01/lazy-loading-singletons.html

有关许多有趣的讨论,请参见http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#dcl 。