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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始


   1、代码:
  1. /*
  2. 对象序列化:
  3. */

  4. import java.io.FileInputStream;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import java.io.ObjectInputStream;
  8. import java.io.ObjectOutputStream;
  9. class ObjectStreamDemo
  10. {
  11.         public static void main(String[] args) throws Exception
  12.         {
  13.      writeObj();
  14.      readObj(); <font color="#ff8c00">
  15. <b>//</b></font><font color="#ff8c00"><b>问题就出现在这两个方法的调用上面</b></font>
  16.                
  17.         }
  18.         //反序列化
  19.         public static void readObj() throws Exception
  20.         {
  21.                 ObjectInputStream ois=new ObjectInputStream
  22.                         (new FileInputStream("obj.txt"));
  23.                 Person p=(Person)ois.readObject();
  24.                 System.out.println(p);
  25.                 ois.close();
  26.         }

  27.         //序列化
  28.         public static void writeObj() throws IOException
  29.         {
  30.                 ObjectOutputStream oos=new ObjectOutputStream
  31.                         (new FileOutputStream("obj.txt"));
  32.                
  33.                 //注意这个地方country字段的值"china" 不会被序列化到obj.txt
  34.                 oos.writeObject(new Person("zsw",22,"china"));
  35.                 oos.close();
  36.         }
  37. }
复制代码
  1. /*
  2. 标记接口:
  3. Serializable
  4. 可序列化的成员:
  5. ①堆里面非静态的字段可以被序列化,
  6. ②方法区里面的静态成员不能被序列化
  7. ③用关键字transient 修饰的不能被序列化
  8. */

  9. import java.io.*;
  10. class Person implements Serializable
  11. {
  12.     public static final long serialVersionUID = 42L;

  13.         private String name;
  14.     private int age;
  15.    
  16.         //静态字段不会被序列化
  17.         private static String country="cn";
  18.         Person(String name,int age,String country)
  19.         {
  20.                 this.name=name;
  21.                 this.age=age;
  22.                 this.country=country;

  23.         }

  24.         public String toString()
  25.         {
  26.                 return name+":"+age+":"+country;
  27.         }
  28. }
复制代码
2、看main方法里面那两个方法的调用:
   1)①先注释掉ReadObj(),只调用 writeObj(); 方法,②然后注释掉 writeObj(); 只调用readObj()方法   
        结果是:zsw:22:cn  
                 ——>
      
      
   2) 把两个方法的注释都去掉,一次直接调用,发现结果变成    :zsw:22:china
       ——>
                这是怎么回事,结果变成了  china???

   我晕,本来以为反正是先调用writeObj,在调用readObj,一次运行应该没问题,一运行,就惊奇的发现变成china了。


评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

6 个回复

倒序浏览
无语了,沙发都没有人要。。。
回复 使用道具 举报
这个问题你刚提出来,我就看到了,我也奇了怪了,为什么呢,先把帖子收藏了,今天下午又重新研究了一遍老毕的视频,还是不得其解。
没办法耗时间太长了,咱们只能根据现象猜一个答案了,我也想不通,所以只能把我理解的说出来,不过这个解释没道理。呵呵
看main方法里面那两个方法的调用:
   1)①先注释掉ReadObj(),只调用 writeObj(); 方法,②然后注释掉 writeObj(); 只调用readObj()方法   
        结果是:zsw:22:cn  
这个就是老师视频中的讲解,虽然new了一个对象,但因为有个成员变量是static修饰的,存放于方法区中,没有被序列化。

2) 把两个方法的注释都去掉,一次直接调用,发现结果变成    :zsw:22:china
根据打印结果,可以确定china肯定是从堆内存中取出来的,因为方法区中的是cn.但是为什么不是从方法区去取,这个实在不明白。
我感觉writeObj();
         readObj();
这两句如果联系在一起执行,程序其实开始没有读取硬盘数据,而是直接在内存中完成了操作。

说实话,这个问题我真不会,但是心里被这个问题堵得难受,只能把自己的想法写出来,不过是错误答案,自己真不知道正确答案,供各位大侠拍板砖,希望有大侠尽快解答。
      
回复 使用道具 举报
黑马振鹏 发表于 2012-7-22 17:47
这个问题你刚提出来,我就看到了,我也奇了怪了,为什么呢,先把帖子收藏了,今天下午又重新研究了一遍老毕 ...

这估计与内存分配有关系,
回复 使用道具 举报
该方法中writeObj()方法和readObj()方法不能同时执行!;
如果同时执行了,你想一下,static的确不能序列化;
但是你有个new Person("zsw",22,"china")的行为,person的static字段只在内存中有一份!
所以你的new person()是改变了内存中的country!此时country为china了;
当然之后你readObject();由于static原本就没有序列化进去;
所以这时不会变得。依旧是china;主要是你有个new person()!

你也可以这么试一下。在main中写
Person ee=new Person("ll",19,"kr");
readObj();
你会的得到zsw:21:kr;
原理一样,就不解释了;是内存中static字段改变了!
回复 使用道具 举报
不明白,但是我给你试了试

我又试了将Person.java的构造方法的
this.country = country这一句话给注释了 结果两次运行肯定是一样的,说明chain肯定给了country,是在内存中还是硬盘上就不清楚

然后
第一次  生成的txt文件命名为obj.txt
第二次  生成的txt文件为obj1.txt
然后 我比较了这两个txt文件  是相同的,这说明 两次运行结果在硬盘上是一样的,所以可以肯定第二次是从内存中读取的

K0[[W7LWGG(ASOZ3Y`~VE@A.jpg (32.27 KB, 下载次数: 82)

K0[[W7LWGG(ASOZ3Y`~VE@A.jpg

评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

回复 使用道具 举报
张頔 发表于 2012-7-22 21:20
不明白,但是我给你试了试

我又试了将Person.java的构造方法的

哈哈,都是调试高手啊
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马