Serializable接口的背后

序列化是什么?

  序列化就是将一个对象的状态(各个属性量)保存起来,而后在适当的时候再得到。序列化分为两大部分:序列化和反序列化。java

  • 序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输。
  • 反序列化就是打开字节流并重构对象。对象序列化不只要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例

何时使用序列化: 

  • 对象序列化能够实现分布式对象。主要应用例如:RMI要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时同样。
  • java对象序列化不只保留一个对象的数据,并且递归保存对象引用的每一个对象的数据。能够将整个对象层次写入字节流中,能够保存在文件中或在网络链接上传递。利用对象序列化能够进行对象的"深复制",即复制对象自己及引用的对象自己。序列化一个对象可能获得整个对象序列。

序列化的特色:

  • 若是某个类可以被序列化,其子类也能够被序列化。若是该类有父类,则分两种状况来考虑,若是该父类已经实现了可序列化接口。则其父类的相应字段及属性的处理和该类相同;若是该类的父类没有实现可序列化接口,则该类的父类全部的字段属性将不会序列化。 (2)声明为static和transient类型的成员数据不能被序列化。由于static表明类的状态, transient表明对象的临时数据;
  • 相关的类和接口:在java.io包中提供的涉及对象的序列化的类与接口有ObjectOutput接口、ObjectOutputStream类、ObjectInput接口、ObjectInputStream类。
    • ObjectOutput接口:它继承DataOutput接口而且支持对象的序列化,其内的writeObject()方法实现存储一个对象。ObjectInput接口:它继承DataInput接口而且支持对象的序列化,其内的readObject()方法实现读取一个对象。
    • ObjectOutputStream类:它继承OutputStream类而且实现ObjectOutput接口。利用该类来实现将对象存储(调用ObjectOutput接口中的writeObject()方法)。ObjectInputStream类:它继承InputStream类而且实现ObjectInput接口。利用该类来实现读取一个对象(调用ObjectInput接口中的readObject()方法)。


  对于父类的处理,若是父类没有实现序列化接口,则其必须有默认的构造函数(即没有参数的构造函数)。不然编译的时候就会报错。在反序列化的时候,默认构造函数会被调用。可是若把父类标记为能够序列化,则在反序列化的时候,其默认构造函数不会被调用。这是为何呢?这是由于Java 对序列化的对象进行反序列化的时候,直接从流里获取其对象数据来生成一个对象实例,而不是经过其构造函数来完成。安全

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * Author: Leo Sun
 * Blog: http://kaffa.im/
 * Date: Aug 12, 2014
 */
public class SerializableDemo {

    public static void main(String[] args) {
        Cat cat = new Cat();
        try {
            FileOutputStream fos = new FileOutputStream("catDemo.out");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            System.out.println(" 1> " + cat.getName());
            cat.setName("My Cat");
            oos.writeObject(cat);
            oos.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        try {
            FileInputStream fis = new FileInputStream("catDemo.out");
            ObjectInputStream ois = new ObjectInputStream(fis);
            cat = (Cat) ois.readObject();
            System.out.println(" 2> " + cat.getName());
            ois.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

class Cat implements Serializable {
    
    private static final long serialVersionUID = -5426949996723910122L;
    private String name;

    public Cat() {
        this.name = "new cat";
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

注:writeObject和readObject自己就是线程安全的,传输过程当中是不容许被并发访问的。因此对象能一个一个接连不断的传过来网络

相关文章
相关标签/搜索