输入输出之对象序列化Serializable

1.对象序列化的目标
将对象保存到磁盘中,或允许在网络中直接输出对象。

2.对象序列化的含义
对象的序列化是指将一个Java对象写入IO流中。
对象的反序列化是指从IO流中恢复该java对象。

3.对象序列化机制允许把内存中的java对象转化成与平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上。通过网络将这种二进制流传输到另一个网络节点。其他程序一旦获得了这种二进制流,都可以将这种二进制流恢复成原来的java对象。对象序列化机制使得对象可以脱离程序的运行而独立存在。

4.如果需要让某个对象支持序列化机制,则必须让它的类是可序列化的。为了让某个类是可序列话的,该类必须实现如下两个接口之一:
Serializable
Externalizable

5 .使用Serializable来实现序列化非常简单,主要是让目标类实现Serializable标记接口即可,无须实现任何方法。

6.一旦某个类实现了Serializable接口,该类的对象就是可序列化的,通过两个步骤来序列化该对象:
(1)创建一个ObjectOutputStream,这个输出流是一个处理流。
ObjectOutputStream oos = new ObjectOutputStream(
                    new FileOutputStream("object.txt"));   
(2)调用 ObjectOutputStream对象的writeObject()方法输出可序列化对象。
oos.writeObject(p);

7.从二进制数据中恢复java对象,则需要使用反序列化,步骤如下:
(1)创建一个ObjectInputStream输入流,这个输入流是一个处理流。
ObjectInputStream ois = new ObjectInputStream(
                    new FileInputStream("object.txt"));   
(2)调用 ObjectInputStream对象的readObject()方法读取流中的对象,该方法返回一个Object类型的Java对象,如果程序知道该Java对象的类型,则可以将对象强制类型转换成其真实的类型。
Person p = (Person)ois.readObject();

8.实例
static public void writeObjectFunc(){
        try {
            ObjectOutputStream oos = new ObjectOutputStream(
                    new FileOutputStream("object.txt"));
            Person p = new Person("Jack", 26);
            oos.writeObject(p);
            oos.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

static public void readObjectFunc(){
        try {
            ObjectInputStream ois = new ObjectInputStream(
                    new FileInputStream("object.txt"));
            try {
                Person p = (Person)ois.readObject();
                ois.close();
                System.out.println(p);
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }  

public class Person implements Serializable{
    
    private String name = null;
    private int age = 0;
     
    public Person(String name,int age){
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    
    public String toString(){
        return getClass().getName()+"[name="+name+",age="+age+"]";
    }
}  

9.注意:
1.反序列化数据读取的仅仅是Java对象的,而不是Java类。因此采用反序列化恢复Java对象时,必须提供该Java对象所属类的class文件,否则将会引发ClassNotFoundException。
2.使用序列化机制向文件中写入多个java对象,使用反序列化恢复对象时,必须按照实际写入的顺序读取。

10.对象引用的序列化
当程序序列化一个对象时,如果该对象持有另一个对象的引用,为了在反序列化时可以正常恢复该对象,程序会顺带将引用对象也进行序列化,所以引用对象必须是可序列化的。

11.Java序列化机制的序列化算法
(1)所有保存到磁盘中的对象都有一个序列化编号。
(2)当程序试图序列化一个对象时,程序将先检查该对象是否已经被序列化过,只有该对象从未被序列化过,系统才会将该对象转换成字节序列并输出。
(3)如果某个对象已经序列化过,程序将只是直接输出一个序列化编号,而不是重新序列化该对象。
当多次调用writeObject()输出同一个对象时,只有第一次调用writeObject()方法时才会将对象转换成字节序列并输出。





  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值