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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 田向向 于 2012-7-6 09:21 编辑

毕老师的Java基础视频教程第06天-09-面向对象(单例设计模式)这个视频我没看明白。

package mianxiangduixiang;
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());
}
}

  System.out.println(s2.getNum());输出的结果为什么是23??我这个视频我看了三遍,还是没弄明白,求高手指点,请说的详细一点,通俗一点,谢谢!!!

8 个回复

倒序浏览
既然是单例 那内存中肯定只有一份了。

private static Single s = new Single();定义成static 那么内存中只会有一个 s  ,他指向你new的 single()

Single s1 = Single.getInstance();
Single s2 = Single.getInstance();
当调用方法时,由于方法返回 s, 那么s 中的值将赋给s1 s2,现在s1 s2 内存的是同一个值,都指向同一个 Single 对象。

所以当 s1.setNum(23); 改变num 值时,用s2.getNum() 和用s1.getNum() 返回一样的结果。


点评

谢谢  发表于 2012-7-6 09:20

评分

参与人数 1技术分 +1 收起 理由
黑马张扬 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 翁游龙 于 2012-7-6 00:09 编辑

先跟你说说概念:
单例模式:其实就是为了保证一个类仅有一个实例,并提供一个访问它的全局访问点。

其次再来看程序:
程序中已经把构造方法私有化了,所以只能在Single本类中访问,超过了Single这个类
就不能访问,所以此时在Single本类中必须对外提供一个访问它的方法。而为了保证
类中只有一个实例,我们在Single本类中自己创建了一个对象,并且要定义成私有的

为了访问被外界访问,接着再对外提供一个获取本类实例的全局方法,那么此时外界
只能通过这个全部方法来获取这个类的实例,而这个类自始自终只有一个实例,所以

在主函数中不管掉用多少次getInstance()这个方法,获取的都是同一个实例,所以输出
结果就是23。
给你举个例子,比如:
Demo d1 = new Demo();
Demo d2 = d1;
d2.setNum(21);
System.out.println(d2.num); //结果是21
System.out.println(d1.num);//结果还是21

点评

谢谢  发表于 2012-7-6 09:20

评分

参与人数 1技术分 +1 收起 理由
黑马张扬 + 1

查看全部评分

回复 使用道具 举报
package mianxiangduixiang;
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;  //外界只要调用getInstance()方法就返回本类创建的唯一的对象...不过调用多少次都只有这一个对象...
}
}

class SingleDemo
{
public static void main(String[] args)
{
  Single s1 = Single.getInstance();//这两句调用getInstance(),返回的都是那一个对象,所以两个引用指向了同一个对象,所以其中一个改变了成员变量的值,另一个获取的就是改变后的值..
  Single s2 = Single.getInstance();
  s1.setNum(23);
  System.out.println(s2.getNum());
}
}

点评

谢谢  发表于 2012-7-6 09:21
回复 使用道具 举报
  1. package mianxiangduixiang;
  2. class Single
  3. {
  4.         private int num;
  5.         public void setNum(int num)
  6.         {
  7.           this.num=num;
  8.         }
  9.         public int getNum()
  10.         {
  11.           return num;
  12.         }
  13.         private  Single(){}
  14.         private static Single s = new Single();//这个对象在类中被初始化,称为本类对象,于是开辟了内存A
  15.         public static  Single getInstance()
  16.         {
  17.           return s;//这里返回的就是已经初始化好的对象
  18.         }
  19. }

  20. class SingleDemo
  21. {
  22.         public static void main(String[] args)
  23.         {
  24.           Single s1 = Single.getInstance();//s1指向了上面那个本类对象,实际就是指向了内存A
  25.           Single s2 = Single.getInstance();//同样,s2也指向了内存A
  26.           s1.setNum(23);//s1改变了内存A的内容
  27.           System.out.println(s2.getNum());//s2是指向内存A的,内存A已经被s1.setNum(23);改变了,s2获得的值当然也改变了.
复制代码
这就像有两伙人想揍你,他们都有你家的地址,无论是哪伙把你揍了.你都获得了鼻青脸肿的状态,其他人到你家找你,都发现你是鼻青脸肿的.
开个玩笑,是你要我说得通俗点的,可能还有点粗俗...{:soso_e112:}

点评

谢谢哈  发表于 2012-7-6 09:20

评分

参与人数 1黑马币 +2 收起 理由
田向向 + 2

查看全部评分

回复 使用道具 举报
丁二跃 发表于 2012-7-6 00:00
既然是单例 那内存中肯定只有一份了。

private static Single s = new Single();定义成static 那么内存中 ...

我分步骤解释一下
首先明确一点
private static Single s = new Single();因为 Single s定义为静态,所以在类加载进类存时,在堆内存中创建了一个Single对象,并且s指向 Single对象。因为构造函数定义为私有(private ),所以无法再其他类中调用次构造函数,也就是说无法再其他类中创建Single对象,所以Single对象只能在类加载的时候创建,并且只能创建一次,所以对内存中只存在唯一一个Single对象,该对象就是类加载时创建的。

1.Single s1 = Single.getInstance();  //让s1指向堆内存中的那个Single对象

2.Single s2 = Single.getInstance();  //让s2也指向堆内存中的那个Single对象

3.s1.setNum(23);  //对s1指向的对象做修改其实也就是对s2指向的那个对象做修改,因为他们指向的是同一个Single对象。

点评

谢谢  发表于 2012-7-6 09:21
回复 使用道具 举报
我分步骤解释一下
首先明确一点
private static Single s = new Single();因为 Single s定义为静态,所以在类加载进类存时,在堆内存中创建了一个Single对象,并且s指向 Single对象。因为构造函数定义为私有(private ),所以无法再其他类中调用次构造函数,也就是说无法再其他类中创建Single对象,所以Single对象只能在类加载的时候创建,并且只能创建一次,所以对内存中只存在唯一一个Single对象,该对象就是类加载时创建的。

1.Single s1 = Single.getInstance();  //让s1指向堆内存中的那个Single对象

2.Single s2 = Single.getInstance();  //让s2也指向堆内存中的那个Single对象

3.s1.setNum(23);  //对s1指向的对象做修改其实也就是对s2指向的那个对象做修改,因为他们指向的是同一个Single对象。
回复 使用道具 举报
王艺霖 发表于 2012-7-6 00:37
单例是java23种设计模式之一它属于创建型模式(创建对象)单例模式是保证类在内存中只有一个对象 单例模式 ...

王艺霖:lol
回复 使用道具 举报
此单例模式为饿汉式单例,在类加载的时候不创建不创建单例实例,只有在第一次请求实例的时候创建,并且只在第一次创建,以后不再创建该实例,
class SingleDemo
{
public static void main(String[] args)
{
  Single s1 = Single.getInstance();
  Single s2 = Single.getInstance();
  s1.setNum(23);
  System.out.println(s2.getNum());
}
}

你的代码中虽然两次创建单例对象,但是由于实例为static类型,所以该类中只有一个实例,即s1和s2是同一个实例,
虽然你是用s1调用setNum函数,改变num的值,用s2返回num的值,但是由于s1和s2是同一个实例,所以返回的结果也是23
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马