-1

我有一堂课是下面的一堂课..

public class DataBaseDAO { 
    private DataBaseDAO() { }
        public static synchronized DataBaseDAO getInstance() {
            if (dao == null) {
                dao = new DataBaseDAO();
                }
            return dao;
            }
        }
    }

现在这个 getinstance() 方法可以被破解:换句话说,这个单例可以被破解并且可以创建更多对象。

我怎样才能保证这个安全?
这可以通过反射、类加载器和反序列化来解决。
我应该选择同步块而不是对整个方法进行同步吗?
会对性能产生影响吗?

谢谢大家,实际上我不想引入新的枚举,因为在现有的结构中会发生很多变化,我正在寻找如何用当前的方法在类本身内改进现有的单例..!!

4

4 回答 4

2

你可以更安全地做同样的事情

public enum DataBaseDAO { 
    INSTANCE
}

例如,您可以使用反射来使用私有构造函数,setAccessible(true)但不能创建新的枚举实例。

代替

DataBaseDAO.getInstance().whateverMethod()

您可以使用

DataBaseDAO.INSTANCE.whateverMethod()
于 2012-08-08T15:20:52.390 回答
1

实际上你不应该担心你的单例被黑了。通常,单例被认为是一种糟糕的(过时的)设计实践(它们往往会妨碍或迟到,导致可伸缩性问题并使测试变得不必要地复杂)。

你已经定义了一个明确的访问方法,你(作为设计师或程序员)没有责任防止聪明的黑客不择手段地滥用你的单例。有项目指南可以防止这种情况发生。

于 2012-08-08T15:25:41.927 回答
0

您需要使用双重检查锁定,单例模式 检查此链接:

http://www.ibm.com/developerworks/java/library/j-dcl/index.html

http://onjavahell.blogspot.co.il/2009/04/uses-of-singleton-design-pattern-in.html

于 2012-08-08T15:13:23.513 回答
0

以下3种方式都是安全的,前两种通过类加载机制,最后一种通过同步。

此外,除非您使用 SecurityManagers,否则您无法保护自己免受反射,我认为这非常复杂。

另一个注意事项:不要使用单例;-P

class YourClass
{
    public static final YourClass instance = new YourClass();
}

// or

class YourClass2
{
    private static final YourClass2 instance = new YourClass2();

    public static synchronized YourClass2 getInstance()
    {
        return instance;
    }
}

// or

class YourClass3
{
    private static YourClass3 instance;

    public static synchronized YourClass3 getInstance()
    {
        if (instance == null)
            instance = new YourClass3();
        return instance;
    }
}
于 2012-08-08T15:18:29.790 回答