黑马程序员技术交流社区

标题: 采用单例设计模式设计的类真的能完全阻止建立多个对象? [打印本页]

作者: 谢洋    时间: 2013-2-27 20:59
标题: 采用单例设计模式设计的类真的能完全阻止建立多个对象?
采用单例设计模式设计的类能完全阻止建立多个对象?
作者: 李挺    时间: 2013-2-27 21:01
构造方法私有化之后,外界就无法通过构造方法新建对象了
自己本类中建立自己的对象,然后对外提供一个方法,让外界获得对象
由于这个对象只能有这个类建立,所以可以实现单例
作者: 陈圳    时间: 2013-2-27 21:19
class Demo11
{
        private static Demo11 d=new Demo11();
        private Demo11()
        {}
        public Demo11 getD()
        {
                return d;
        }
}//无论你怎么创建,反回的都是已经定义好的类对象d.
作者: 何伟    时间: 2013-2-27 21:53
如果还能创建 那还叫单例?
作者: 贾振凯    时间: 2013-2-27 21:59
单例模式在不考虑序列化的情况下,无论勤加载还是懒加载,均是安全的.看你代码是怎么写的了.

但当单例执行了Serializiable接口以后,就不安全了. 将单例序列化再反序列化, 单例就多了一份copy.

但这个问题也不是不能解决,常用的方法有两种:

一. readResolve

public class Singleton implements Serializable {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
}
private Object readResolve() {
//readUnshared 返回该对象的浅表副本
return INSTANCE;
}
public static Singleton getInstance() {
return INSTANCE;
}
}

当进行反序列化时,  ois.readObject();时内部就是通过反射检查implements Serializable的类有没有

readResolve方法,如果有就把readResolve的返回值作为ois.readObject();的返回值. 所以readResolve必须返回之前对象的引用

二. 使用枚举式

使用了枚举特有的特性, 枚举序列化, 反序列化的对象然后是同一个对象. 可以自行查看ois.readObject();oos.writeObject(obj)代码, 它是

把枚举作为一种类型单独考虑的.

作者: Benwolf0818    时间: 2013-2-27 22:05
Singleton模式的实现基于两个要点:
1)不直接用类的构造函数,而另外提供一个Public的静态方法来构造类的实例。通常这个方法取名为Instance。Public保证了它的全局可见性,静态方法保证了不会创建出多余的实例。
2)将类的构造函数设为Private,即将构造函数"隐藏"起来,任何企图使用构造函数创建实例的方法都将报错。这样就阻止了开发人员绕过上面的Instance方法直接创建类的实例。
通过以上两点就可以完全控制类的创建:无论有多少地方需要用到这个类,它们访问的都是类的唯一生成的那个实例。
作者: 胥文    时间: 2013-2-27 22:28
首先是不能阻止创建多个对象的
当反射出现的时候一切就变了
你可以通过反射来获取他私有的构造方法
然后再创建n个对象
eg:
class SingelDemo
{
        private SingelDemo(){}
        private static SingelDemo sd = new SingelDemo();
        public static SingelDemo getInstance()
        {
                return sd;
        }
        public void show()
        {
                System.out.println("hello");
        }
}

public class Test5 {

        public static void main(String[] args) throws SecurityException, Exception {
                //这是之前创建对象的方法
                SingelDemo sd1 = SingelDemo.getInstance();
                sd1.show();
               
                //通过反射获取构造函数,并创建多个对象
                Constructor constructor = SingelDemo.class.getDeclaredConstructor();
                constructor.setAccessible(true);
                SingelDemo sd2 = (SingelDemo) constructor.newInstance();
                SingelDemo sd3 = (SingelDemo) constructor.newInstance();
                SingelDemo sd4 = (SingelDemo) constructor.newInstance();
                SingelDemo sd5 = (SingelDemo) constructor.newInstance();
                System.out.println(sd2.equals(sd3));
                sd2.show();
                sd3.show();
               
               
               
        }

}
作者: amen0205    时间: 2013-2-28 02:43
单例设计模式的思想就是  把构造函数私有化  使外界不能用该构造函数创建对象  并提供一个方法被外界调用来创建唯一对象  不能保证这一点  就不是单例设计模式了
作者: 移动小坦克    时间: 2013-2-28 21:26
如果是叫真,懒汉式如果不加锁,在遇到多线程的时候是可能出问题的,这个在教学视频时说的很清楚了。
就是在判断完if语句后,失去执行权,然后别的线程进入,由于前一个线程,只是判断完if语句,但是并没有生成对象,
所以第2个线程也可以通过if语句
作者: 明锦添    时间: 2013-3-4 22:45
单例设计模式的思想就是  把构造函数私有化  使外界不能用该构造函数创建对象  并提供一个方法被外界调用来创建唯一对象




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2