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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 杨增坤 金牌黑马   /  2013-9-5 12:03  /  1300 人查看  /  12 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 杨增坤 于 2013-9-5 19:35 编辑

在总结单例设计模式的时候遇到的疑问。
  把实例化的对象定义成公有的且静态的后,这样就可以不用使用方法来返回,这样也可以防止多线程出现异常,就可以用类名直接调用了。这样不就更方便呢啊!
  
public class Single {
  
  public static Single s = new Single();
  
  private Single() {}
  
}
  
public class SingleDemo {
  
  public static void main(String[] args) {
  
       Single s1=Single.s;        
  
  }
  
}
  


难道这是那是写代码的习惯??那样写更符合写程序的规则吗??是这样理解?

12 个回复

倒序浏览
这样的话你在主函数里多次调用Single.s的话,会创建多个对象!
  1. public class SingleDemo {
  2.   
  3.   public static void main(String[] args) {
  4.   
  5.        Single s1=Single.s;//创建对象s1
  6.        Single s2=Single.s;//创建对象s2   
  7.   
  8.   }
  9.   
  10. }
复制代码
回复 使用道具 举报
二楼的说法不对,重复引用s是不会重复创建对象的,静态代码,在类首次被加载到虚拟机中时,就会被分配到内存空间,切指挥执行一次。而后,根本就没有机会再次调用到new Single();所以不会重复创建对象。
至于楼主的问题。其实你的写法没有错,但是,思想不对。
因为Java是面向对象的语言。程序的设计因该遵循面向对象的思想。面向对象的额特征之一,封装。
类中的属性都应该进行封装,Single s是Single类中的属性,应该对其进行封装。并对外提供一个方法使外部能对其调用。
所以说,楼主的写法没有错。但是不应该这么写

评分

参与人数 1技术分 +1 收起 理由
杨增坤 + 1

查看全部评分

回复 使用道具 举报
java类中的成员变量都暴露了,不安全。饿汉式比较占用内存空间。
线程是安全的,但不体现java的封装性。{:soso_e113:}
回复 使用道具 举报
假设single有子类的话,那我执行
Single.s = new SubSingle();
不就把那个改了。

其实设计模式更多的是语义上的。而不是语法上的,怎么实现并不重要,重要的是一个类只有一个对象这个语义。
以后用了spring就不用这样来设计了,全都是用配置文件来配置了。配置单例还是多例。
回复 使用道具 举报
昝文萌 发表于 2013-9-5 12:23
这样的话你在主函数里多次调用Single.s的话,会创建多个对象!

public class Single {
        public static Single s = new Single();
        private String name="张三";
        private Single() {}
        public static Single getS() {
                return s;
        }
        public static void setS(Single s) {
                Single.s = s;
        }
        public String getName() {
                return name;
        }
        public void setName(String name) {
                this.name = name;
        }       
       
}
public class SingleDemo {       
        public static void main(String[] args) {
            Single s1=Single.s;               
            System.out.println(s1.getName());
            Single s2=Single.s;
            s2.setName("李四");
            System.out.println(s2.getName());//李四
            System.out.println(s1.getName());//李四
        }
}

但是结构她们还是同一个对象的,而不是多个对象不一样,和用方法执行结果是一样的,


回复 使用道具 举报
夏天那抹蓝╮ 发表于 2013-9-5 13:00
假设single有子类的话,那我执行
Single.s = new SubSingle();
不就把那个改了。

我的那个Single类的构造方法是私有的,他是不可以继承的,不可能有子类,所以你的说法是不正确的吧!
回复 使用道具 举报
Single.s=null;
回复 使用道具 举报

我明白了,懂了,如果这样写的话,就能够设置单例中的对象,那么就把对象暴露了是吧!
说到点子上了!
回复 使用道具 举报
不对吧,你应该把类的构造方法设置成私有的,因为单例模式不能被类外的创建对象,需要加上private,其中static是为了让你的对象只创建一次,看看我说的对不
回复 使用道具 举报
杨增坤 发表于 2013-9-5 22:32
我明白了,懂了,如果这样写的话,就能够设置单例中的对象,那么就把对象暴露了是吧!
说到点子上了!
...

为什么说写Single.s=null,就能够设置单例中的对象,就把对象暴露了呢??  求详细解答。
是说Single s1=Single.s,因为s为nul,所以s1也为null,这样就能够设置单例中的对象?


回复 使用道具 举报
张文豪 发表于 2013-9-8 09:19
为什么说写Single.s=null,就能够设置单例中的对象,就把对象暴露了呢??  求详细解答。
是说Single s1= ...

因为Slinge.s可以为他重新赋值,但是用public Slnge getInsance的话,那么获取出来的对象,虽然也可以重新赋值,再次获取的话,还是原来的值,没哟被覆盖,但是用 Slinge.s,就会覆盖 的。

回复 使用道具 举报
hmwudizl91zl 发表于 2013-9-8 08:25
不对吧,你应该把类的构造方法设置成私有的,因为单例模式不能被类外的创建对象,需要加上private,其中stat ...

但是这样的话,可以呗重新赋值,会覆盖原来的值,如果用方法的话,只有获取的,没有赋值的方法,所以更要全的!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马