1.说明
所有分布式应用常常需要跨平台,跨网络,因此要求所有传的参数、返回值都必须实现序列化。而对象序列化包含序列化和反序列化二部分,序列化是把Java对象转换为字节序列的过程,反序列化是把字节序列恢复为Java对象的过程。
2.用途
对象序列化主要有二种用途,一个是把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中,也叫持久化对象;另一个是在网络上传送对象的字节序列,也叫网络传输对象。
3.实现
序列化需要实现Serializable或Externalizable接口。序列化过程中ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。反序列化过程中ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。
4.示例
要被序列化的实体类
public class Emp implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private static String name; private int age; private transient String dept; public Emp() { super(); } public Emp(String name, int age, String dept) { super(); Emp.name = name; this.age = age; this.dept = dept; } public String getName() { return name; } public void setName(String name) { Emp.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getDept() { return dept; } public void setDept(String dept) { this.dept = dept; } @Override public String toString() { return "Emp [name=" + name + ", age=" + age + ", dept=" + dept + "]"; }
该实体类中实现了Serializable接口,并生了默认的serialVersionUID,而且name属性被修饰为static,dept属性添加了transient关键字。
public class TestSerialization { public static void main(String[] args) throws IOException, ClassNotFoundException { /* * 序列化保存对象 */ FileOutputStream foStream = new FileOutputStream("f:"+File.separator+"b.txt"); ObjectOutputStream oos = new ObjectOutputStream(foStream); oos.writeObject(new Emp("张三", 13, "机械部")); oos.writeObject(new Emp("李四", 23, "工程部")); oos.close(); /* * 序列化读取对象 */ FileInputStream fis = new FileInputStream("f:"+File.separator+"b.txt"); ObjectInputStream ois = new ObjectInputStream(fis); Emp emp = (Emp)ois.readObject(); Emp emp1 = (Emp)ois.readObject(); System.out.println(emp); System.out.println(emp1); ois.close(); }
在该测试类中实现了序列化和反序列的过程,结果如下图所示:
从结果中可以得出结论,被static修饰的变量是不参与序列化的,而被transient修饰的变量dept也没有被序列化,其实有时候,我们并不希望出现递归序列化,或是某个存敏感信息(如银行密码)的属性不被序列化,我们就可通过transient关键字修饰该属性来阻止被序列化。
现在将实体类的无参构造添加如下代码
public Emp() { System.out.println("无参构造..."); }
而测试类改变代码为
public class TestSerialization { public static void main(String[] args) throws IOException, ClassNotFoundException { /* * 序列化保存对象 */ FileOutputStream foStream = new FileOutputStream("f:"+File.separator+"b.txt"); ObjectOutputStream oos = new ObjectOutputStream(foStream); oos.writeObject(new Emp("张三", 13, "机械部")); oos.writeObject(new Emp("李四", 23, "工程部")); oos.close(); /* * 序列化读取对象 */ FileInputStream fis = new FileInputStream("f:"+File.separator+"b.txt"); ObjectInputStream ois = new ObjectInputStream(fis); Object emp = ois.readObject(); Object emp1 = ois.readObject(); System.out.println(emp); System.out.println(emp1); ois.close(); } }
结果显示为
结果没有打印“无参构造...”,说明反序列化机制无需通过构造器来初始Java对象。