首页 > 代码库 > java对象序列化

java对象序列化

定义:

  对象序列化目标是将对象保存在磁盘中,允许在网络中直接传输对象。序列化机制把内存中的java对象转化成与平台无关的二进制流,从而可以把这种二进制

流永久的保存在磁盘上,通过网络把二进制流传送到另一个网络节点,其他程序一旦获得了二进制流,不管是从磁盘还是网络获取的,都可以将此转换成java对象。

 

如果要把某个对象序列化,这个对象必须要实现Serializable接口,实现此接口无需实现任何方法,此接口只是告诉java此对象是可以被序列化的。

此接口是一个标记接口。  

被序列化的User对象,

 

import java.io.Serializable;public class User implements Serializable{    private String name;    private int 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;    }}

 

将User对象序列化,创建一个输出流输出到磁盘

public static void main(String[] args) throws Exception{        FileOutputStream fos = new FileOutputStream("d:/object.txt");        ObjectOutputStream oos =new ObjectOutputStream(fos);                User u =new User();        u.setName("jack");        u.setAge(43);                oos.writeObject(u);    }

反序列化,创建一个输入流,从磁盘读取

public static void main(String[] args) throws Exception{        FileInputStream fis = new FileInputStream("d:/object.txt");        ObjectInputStream ois =new ObjectInputStream(fis);                User u =(User)ois.readObject();        //输出 jack    43        System.out.println(u.getName() +"\t"+u.getAge());    }

由此,序列化还是很容易理解的

还有几点说明:

  1.反序列化不是通过构造器来初始化java对象的,可以用构造方法来验证。

  2.如果序列化向文件中写入了多个对象,反序列化必须按照实际写入的顺序读取。

  3.如果被序列化对象的直接或间接父类是不可序列化的,只带有无参数构造器,改父类定义的成员不会被序列化。

    4.被序列化的引用类也必须实现Serializable接口; 

对象引用序列化:

  序列化对象Person 有一个User对象的引用:

import java.io.Serializable;public class Person implements Serializable{    private String id ;    private User u;        public String getId() {        return id;    }    public void setId(String id) {        this.id = id;    }    public User getU() {        return u;    }    public void setU(User u) {        this.u = u;    }}

 

  如果某对象被其他多个不同对象引用,需要序列化,java不会对同意对象做多次序列化,因此java序列有特殊算法(序列化底层机制):

  *所有保存到磁盘的序列化对象都有一个编号。

  *当程序试图序列化对象时,java会先检查此对象在本次虚拟机中是否被序列化过。

  *如果被序列化过,则输出上次序列化的编号,而不是重新序列化改对象。

那么,做个重复序列化测试

    public static void main(String[] args)  {        try{            FileOutputStream fos = new FileOutputStream("d:/object.txt");            ObjectOutputStream oos =new ObjectOutputStream(fos);                        FileInputStream fis = new FileInputStream("d:/object.txt");            ObjectInputStream ois =new ObjectInputStream(fis);                        User u =new User();            u.setName("第一次序列化");            oos.writeObject(u);            u.setName("第二次序列化");            oos.writeObject(u);            //读取流            ois.readObject();            User ui =(User)ois.readObject();            //发现输出 : 第一次序列化            System.out.println(ui.getName() );        }catch(Exception e){            e.printStackTrace();        }    }

发现结果符合它的机制的确没有做二次序列化,即使对象的属性被修改

 

java对象序列化