Java:延迟加载单例和反射攻击



如果我通过持有者习语或双重检查锁定来实现单例,但不是调用"getInstance()",而是使用反射来实例化它,然后在上面调用"getInstance()",这将创建两个实例,打破模式。

因此,我向类添加一个静态"计数器"成员,在类的私有构造函数中递增它,如果它越过"1",则抛出异常。但是在这种情况下,如果我首先通过反射实例化,那么没有其他人能够在不抛出异常的情况下调用"getInstance()"。

那么,如何延迟加载单例并防止它受到此攻击呢?(我知道"Enum"模式,但有些人觉得这实际上是一个黑客。检查对此接受答案的评论:此单例是否同时抵抗序列化和反射攻击?顺便说一句,我的问题不同)。

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

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

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

这出现在Effective Java(第48项)中,但我第一次听说它是从疯狂的鲍勃的一篇文章中。

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

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

最新更新