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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张其辉 中级黑马   /  2012-10-24 13:23  /  2263 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 张其辉 于 2012-10-24 15:45 编辑

import java.io.*;
public class io3 {
        public static void main(String[] args) throws Exception
        {
                writeObj();
                readObj();

        }
        public static void readObj()throws Exception//读取序列化后的文件obj.txt
        {
                ObjectInputStream ois=new ObjectInputStream(new FileInputStream("obj.txt"));
                Person p=(Person)ois.readObject();
                System.out.println(p);
                ois.close();
        }
        public static void writeObj() throws IOException//输出经过序列化的文件,存储在obj.txt中
        {
                ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("obj.txt"));
                oos.writeObject(new Person("lisi", 32,"kr"));//注意这一句country输入的是kr
                oos.close();
        }
}
class Person implements Serializable
{
        public static final long serialVersionUID=42L;
        String name;
        int age;
        static String country="cn";//注意这里定义的是cn
        Person(String name,int age,String country)
        {
                this.name=name;
                this.age=age;
                this.country=country;
        }
        public String toString()
        {
                return name+":"+age+":"+country;
        }
}上面红色的两句,如果注释掉readObj();单独运行writeObj();然后再运行readObj();结果为lisi:32:cn     
如果writeObj();和readObj();都不注释掉,同时存在,运行结果为  isi:32:kr
为什么两次结果不一样呢?
               

评分

参与人数 1技术分 +1 收起 理由
韩军博 + 1 很给力!

查看全部评分

6 个回复

倒序浏览
因为你分两次运行就涉及到了两个对象实例,后一次用的是本地的
回复 使用道具 举报
版主为什么不给我技术分?哼!!
回复 使用道具 举报
刚敲完这段代码,却没发现LZ这个问题,唉,只能说明俺还不够认真、不够细心!

琢磨了好久,也尝试了好久。发表一点看法:

首先,static变量不被序列化。所以反序列化读取的static变量是类中的变量值。(不知道错没错)

不分开运行的时候,static的country值被改变,类中country值为kr。所以当读的时候读的是改变后的country值kr。

分开运行的时候,由于要编译运行两次,当第一次运行writeObj()时,和不分开时一样,类中country值为kr;

但是接着的第二次运行readObj(),static的country值又被赋值为cn。所以读取的country值又回到了cn。

在readObj(),writeObj()前加上 System.out.println(Peson.country) 再运行可以看出点端倪:
import java.io.*;
public class io3 {
        public static void main(String[] args) throws Exception
        {                         //按照需要注释
                  System.out.println(Person.country);
                                  writeObj();
                  System.out.println(Person.country);
                                  readObj();
        }
        public static void readObj()throws Exception//读取序列化后的文件obj.txt
        {
                ObjectInputStream ois=new ObjectInputStream(new FileInputStream("obj.txt"));
                Person p=(Person)ois.readObject();
                System.out.println(p);
                ois.close();
        }
        public static void writeObj() throws IOException//输出经过序列化的文件,存储在obj.txt中
        {
                ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("obj.txt"));
                oos.writeObject(new Person("lisi", 32,"kr"));//注意这一句country输入的是kr
                oos.close();
        }
}
class Person implements Serializable
{
        public static final long serialVersionUID=42L;
        String name;
        int age;
        static String country="cn";//注意这里定义的是cn
        Person(String name,int age,String country)
        {
                this.name=name;
                this.age=age;
                this.country=country;
        }
        public String toString()
        {
                return name+":"+age+":"+country;
        }
}
不分开运行结果:
cn                                  未序列化前count值
kr                                   序列化后country值
lisi:32:kr                       
分开运行结果:
单独运行writeObj()时:  
cn                               未序列化前country值
kr                                序列化后country值
再运行readObj():
cn                               重新赋值后country值
lisi:32:cn
回复 使用道具 举报
兄弟  这其实是都是static 惹得祸,序列化的时候,把对象以二进制的方式存在文本文件中,而且只能保存对象的非静态成员函数,不能保存任何的成员方法和静态的成员变量,而且序列化保存的只是变量的值,对于变量的任何修饰符都不能保存。
class Person implements Serializable {
        public static final long serialVersionUID = 42L;
        String name;
        int age;
        static String country = "cn";//1. 如果把这个static给干掉的话,读写方法一起执行之后,你会发现obj.txt的大小是102字节,而且输出的结果也是 lisi:32:kr;如果你先执行写方法,在执行读方法,其结果仍然是 lisi:32:kr  2.如果没有除掉static的话,执行的时候,obj.txt的大小只有82字节,问题就出现在这儿了,它根本就没有保存到文件中。3.ObjectOutputStream和ObjectInputStream在序列化对象的时候,这个过程本身也是一个序列化与饭序列化的过程。



        Person(String name, int age /* String country */) {
                this.name = name;
                this.age = age;
                /* this.country = country; */
        }

        public String toString() {
                return name + ":" + age + ":" + country;
        }
}

回复 使用道具 举报
本帖最后由 张亮 于 2012-10-24 16:03 编辑

“从 ObjectInputStream 读取对象。对象的类、类的签名和类及所有其超类型的非瞬态和非静态字段的值都将被读取。”这是ObjectInputStream类readObject方法的api文档。
单独运行读写,读的时候,静态的country没被读出来。country是静态属性,所有对象共有。此时Person类的country值是cn。因此,就是这个结果了。
读写一起运行的时候,静态的country还是没被读出来。只是此时Person类的country值是cr。因此,就是那个结果了。
给加分啊!!!费了我好长时间呢!!!!!
回复 使用道具 举报
明白了,终于看出端倪了,谢谢各位大侠{:soso_e183:}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马