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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© panningwjr 中级黑马   /  2013-8-7 14:34  /  2559 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

今天复习io流,其中讲到可以将对象写入本地文件存储起来,还可以通过输入流读取对象,如下

如果我将单例的对象写入本地文件,再读取,岂不是破坏了单例吗?
从代码中可以看出p和p1明显是两个对象

评分

参与人数 2技术分 +2 黑马币 +3 收起 理由
滔哥 + 2
以防万一 + 3 赞一个!

查看全部评分

10 个回复

倒序浏览
这涉及到对象的比较问题,“==”肯定不能比较两个对象是否是同一个对象,因为它比较的是对象的引用是否相同而非对象的内容是否相同。equal也不一定能比较两个对象是否相同,因为类的equal方法继承自Object类,在Object类里equal其实就一句话,if(a==b),return true。也就是说Object将比较对象内容是否相同的人物留给了类的设计者,在String类中,重写了equal方法,所以可以通过equal方法比较两个字符串的内容是否相同,而自己定义的类需要自己去重写equal方法。不重写的话,比较的就是对象的引用是否相同,效果等同于用==。
回复 使用道具 举报
本帖最后由 肥猫 于 2013-8-7 17:47 编辑

你这个就是反序列化机制对单例模式的破坏了,对于这个只要在你的单例源码总加上readResolve()这个方法就能防止反序列化的破坏.
  1. public class Singleton implements Serializable{

  2. /**
  3. *
  4. */
  5.           private static final long serialVersionUID = 1L;
  6.           private String name;
  7.           private static Singleton s;
  8.           private Singleton(String name){
  9.           this.name = name;
  10.       }

  11.           private Object readResolve()throws ObjectStreamException{
  12.               return s;
  13.       }
  14.         @Test
  15.          public static Singleton getInstance(String name){
  16.          if(s == null){
  17.               synchronized(Singleton.class){
  18.          if(s ==null){
  19.               s = new Singleton(name);
  20.            }
  21.        }
  22. }
  23.      return s;
  24.     }
  25. }
复制代码
  1. public class SingletonTest implements Serializable {

  2. /**
  3. *
  4. */
  5.        private static final long serialVersionUID = 1L;

  6.        public static void main(String[] args)throws Exception {

  7.            Singleton s = Singleton.getInstance("一条大菜狗");
  8.            Singleton s2 = null;
  9.            ObjectOutputStream oos = null;
  10.            ObjectInputStream ois = null;
  11.            Thread t1 = new Thread(new ThreadTest());
  12.            Thread t2 = new Thread(new ThreadTest());
  13.            t1.start();
  14.            t2.start();
  15.            try{
  16.                  oos = new ObjectOutputStream(new FileOutputStream("b.bin"));
  17.                  ois = new ObjectInputStream(new FileInputStream("b.bin"));
  18.                  oos.writeObject(s);//序列化S
  19.                  oos.flush();
  20.                  s2 = (Singleton)ois.readObject();//反 序列化S2
  21.                  System.out.println(s==s2);
  22.                }finally{
  23.                if(oos!=null){
  24.                  oos.close();
  25.                   }
  26.                if(ois!=null){
  27.                  ois.close();
  28.                }
  29.            }
  30.       }
  31. }
复制代码

评分

参与人数 1技术分 +2 收起 理由
滔哥 + 2

查看全部评分

回复 使用道具 举报 1 0
任亚俊 发表于 2013-8-7 15:49
这涉及到对象的比较问题,“==”肯定不能比较两个对象是否是同一个对象,因为它比较的是对象的引用是否相同 ...

“==”比较地址,string类覆写后的“equals”比较字符串的内容。
回复 使用道具 举报
如果我将单例的对象写入本地文件,再读取,岂不是破坏了单例吗?////反射技术本来就是与单例模式想冲突的,所以一般遇到这种问题是很正常的,记住有这回事就好!
从代码中可以看出p和p1明显是两个对象
回复 使用道具 举报
心灵之歌 发表于 2013-8-7 20:51
如果我将单例的对象写入本地文件,再读取,岂不是破坏了单例吗?////反射技术本来就是与单例模式想冲突的, ...

请问关反射什么事?哪里跟反射挂了钩?>
回复 使用道具 举报
肥猫 发表于 2013-8-7 17:42
你这个就是反序列化机制对单例模式的破坏了,对于这个只要在你的单例源码总加上readResolve()这个方法就能防 ...

肥猫不错哦,肥猫你这个点是查看 readObject 源码想到的,还是网上搜到到滴!
回复 使用道具 举报
本帖最后由 肥猫 于 2013-8-7 22:11 编辑
toShareBeauty 发表于 2013-8-7 21:59
肥猫不错哦,肥猫你这个点是查看 readObject 源码想到的,还是网上搜到到滴! ...

看书看到的,是一本比较偏底层的书,有讲源码,所以有注意到这个点然后自己试了一下,这个知识点对底层没兴趣的一般也不会涉及到的。
回复 使用道具 举报 1 0
肥猫 发表于 2013-8-7 22:09
看书看到的,是一本比较偏底层的书,有讲源码,所以有注意到这个点然后自己试了一下,这个知识点对底层没兴 ...

恩 {:soso_e179:}            
回复 使用道具 举报
肥猫 发表于 2013-8-7 17:42
你这个就是反序列化机制对单例模式的破坏了,对于这个只要在你的单例源码总加上readResolve()这个方法就能防 ...

哦,了解,其实还是破坏了单例,只要加上readResolve()这个方法就可以避免了,谢谢了!
回复 使用道具 举报
单例模式目的是为了避免在程序中产生过多的对象而占用大量的内存。把对象持久化。又读回来,得到的是原对象可被序列化的属性信息。本来就就不是同一个对象,对象地址也肯定不一样,但程序中并没有产生过多对象。只是产生了一个和原来对象属性一样(也可能属性信息更少的)另一 个对象而已。和单例设计没什么关系吧!

评分

参与人数 1技术分 +1 收起 理由
Sword + 1

查看全部评分

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