A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 尹善波 中级黑马   /  2012-7-30 01:07  /  2326 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文


//单例设计模式
class Single
{
    private int num;
public void setNum(int num)
{
   this.num=num;
}
public int getNum()
{
   return num;
}
   
private  Single(){}//构造这个空的构造函数有具体的用途吗,有的话是什么?
private static Single s = new Single();//创建这个本类对象难道就能禁止其他程序创建该类对象吗;
                                        //有什么用途?

public static  Single getInstance()
{
  return s;
}
}
class SingleDemo
{
public static void main(String[] args)
{
  Single s1 = Single.getInstance();
  Single s2 = Single.getInstance();
  s1.setNum(23);
  System.out.println(s2.getNum());//为什么s2调用getName方法会返回s1设置的值,
                                  //请详细说明,要是有具体步骤更好
}
}
/*
单例设计模式的总体思想是什么,能不能用好理解的话说说?
单例设计模式能保证对象的唯一,但是什么情况下才会运用到呢
*/

4 个回复

倒序浏览
构造函数私有化是为了不让别的类随便new这个类。
在本类中,new自己的静态对象,通过一个公有的方法返回这个对象。这样就形成了单例设计模式
只需要使用一个单独的资源,并且需要共享这个单独资源的状态信息时,就能用到单例模式。
单例最具体的一个例子就是播放器,不能同时听两个界面的歌曲,当播放时再想打开另一个时,当前窗口关闭。
回复 使用道具 举报
本帖最后由 陈汉维 于 2012-7-30 01:35 编辑

private  Single(){}//构造这个空的构造函数有具体的用途吗,有的话是什么?
该空的构造函数式私有的,为了不允许其他程序用new创建该类对象。

private static Single s = new Single();//创建这个本类对象难道就能禁止其他程序创建该类对象吗;//有什么用途?
用途是:在该类创建一个本类实例

public static  Single getInstance()
{
  return s;
}这个用于对外提供一个方法让其他程序可以获取该对象

System.out.println(s2.getNum());//为什么s2调用getName方法会返回s1设置的值
因为Single s1 = Single.getInstance();和Single s2 = Single.getInstance();都必须通过Single里面的getInstance()方法获取已创建的对象,
也就是说对象s1和s2是相等的,他们有一样的内存地址。所以System.out.println(s2.getNum());返回的是同一个内存地址里面的值

单例设计模式:就是为了保证一个类在内存中的对象唯一性。
比如window下的回收站,它是唯一的,运用的就是单例设计模式。你手动点开回收站,然后最小化,然后在点开一个新的回收站,最小化的那个回收站就会展开,不能同时打开2个回收站,这就是单例设计模式。

评分

参与人数 1技术分 +1 收起 理由
田向向 + 1 赞一个!

查看全部评分

回复 使用道具 举报
private  Single(){}//构造这个空的构造函数有具体的用途吗,有的话是什么?
答:构造函数当然是构造对象用的。当你实例化一个对象的时候就会调用构造函数。之所以是private的,就为了只能类内部调用,也就是只能在这个类的内部构造对象。

private static Single s = new Single();//创建这个本类对象难道就能禁止其他程序创建该类对象吗;
                                        //有什么用途?
答:访问控制符为private就是为了不让别人直接调用,只能内部调用。定义为static的就是为了只产生一个对象,因为static的在加载类的时候就会实例化。以后用就是了,不会再产生新的对象。

System.out.println(s2.getNum());//为什么s2调用getName方法会返回s1设置的值,
                                  //请详细说明,要是有具体步骤更好
答:单例单例,顾名思义,只会有一个对象,所以s1和s2指向的是同一个对象,那操作s1和操作s2也是在操作同一个对象,所以返回值是s1设置的。s1和s2相当于两个遥控器,但是它们遥控的是同一台电视机。

至于什么时候能用到,比如你做一个五子棋游戏,那些棋子都是一样的,如果每一个你都new一个对象的话,就太多对象了,太难管理,影响效率,这时就可以用单例来解决,也就是传说中的享元模式。

评分

参与人数 1技术分 +1 收起 理由
田向向 + 1 赞一个!

查看全部评分

回复 使用道具 举报
以上单例的思想说得都很好,我就补充点吧!
创建单例通常分两种方式:
   饿汉模式:
   class Single{
         private Single{}
         private static Single instance = new Single();//对象直接实例化
         public static Single getInstance(){
                 return instance;
         }
   }
   懒汉模式(非终极版):
     class Single{
            private Single{}
           private static Single instance = null;//对象先不实例化
                   public static Single getInstance(){
                    if(instance == null)
                           instance = new Single();//实例在此处加载
                    return instance;
                   }
      }
     两种都是创建单例,普通情况下没什么区别,但在碰到多线程问题时,懒汉模式就会碰到问题。因为懒汉模式的特点就是 实例的延迟加载,有可能两个线程同时判断了满足了为null的条件,第一个还没实例化等着,第二个就实例了,接着第一个就不需要判断又实例化一遍,创造的实例就不是一个了,有违单例思想。为了处理这种问题,就只有给懒汉模式的单例加锁,如下(并非最终版):
     public static synchronized Single getInstance(){//通过synchronized给加锁
        if(instance == null)
                                         instance = new Single();
         return instance;
                       }
    加完锁后,又会碰到一个问题,就是每次调用时都会判断是否有锁,这样效率很低。因此接着改进:
   public static Single getInstance(){
         if(instance == null){
               synchronized(Single.class){        
                         if(instance == null)
                                                                            instance = new Single();
               }
          }
         return instance;
                          }
    这样就解决了效率的问题,只是多个线程加载单例的实例时才会上锁,只要有一个实例加载完了,之后的线程就不用判断锁了。(给人感觉是,懒汉虽懒,考虑的问题还是挺多的。建议开发中用饿汉模式)。

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马