首页 > 代码库 > 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对象序列化