java中的序列化和反序列化简析
本文阅读目录
一、什么是序列化和反序列化
二、序列化和反序列化的主要作用
三、实现序列化和反序列化的必备条件
四、如何实现序列化和反序列化
五、代码实现
Java 序列化(Serialization):把java对象转换为字节序列的过程
java反序列化(Anti-Serialization):通过这些字节序列在内存中新建java对象的过程。
一个类的对象要想序列化成功,必须满足两个条件:
1.实现 java.io.Serializable 接口
2.该类的所有属性必须是可序列化的。如果有一个属性不是可序列化的,则该属性必须注明是短暂的(transient)。
类 ObjectInputStream 和 ObjectOutputStream 是高层次的数据流,它们包含反序列化和序列化对象的方法。
1.ObjectOutputStream类中:使用writeObject(Object x) 方法进行序列化。
public final void writeObject(Object x) throws IOException
2.ObjectInputStream 类:使用Object readObject() 方法进行反序列化。
public final Object readObject() throws IOException, ClassNotFoundException
雇员实体类(Employee.java)
1 package com.cdh; 2 3 /** 4 * @author chudonghai 5 * @editor 6 * @date 2019年9月23日 下午2:16:27 7 * @version v1.0 8 * @since 1.0 9 * @ClassName Employee 10 * @Description 雇员类 11 */ 12 public class Employee implements java.io.Serializable 13 14 { 15 /** 16 * generated serial version ID 17 */ 18 private static final long serialVersionUID = -4308926516970571240L; 19 20 public String name; 21 public String address; 22 public transient int SSN; 23 public int number; 24 25 /** 26 * 描述:写这个方法的目的,纯粹是为了让类更加完整,没别的目的。不要纠结这个。 27 * */ 28 public void mailCheck() { 29 System.out.println("Mailing a check to " + name + " " + address); 30 } 31 }
序列化实现Demo:
1 package com.cdh; 2 /** 3 * @author chudonghai 4 * @editor 5 * @date 2019年9月23日 下午2:29:01 6 * @version 7 * @since 8 * @ClassName SerializationDemo 9 * @Description 序列化实现Demo 10 */ 11 import java.io.*; 12 13 public class SerializationDemo 14 { 15 public static void main(String [] args) 16 { 17 Employee e = new Employee(); 18 e.name = "chudonghai"; 19 e.address = "beijing"; 20 e.SSN = 999999999; 21 e.number = 101; 22 try 23 { 24 FileOutputStream fileOut = 25 new FileOutputStream("E://aaa//employee.ser"); 26 ObjectOutputStream out = new ObjectOutputStream(fileOut); 27 out.writeObject(e); 28 out.close(); 29 fileOut.close(); 30 System.out.printf("Serialized data is saved in E:/aaa/employee.ser"); 31 }catch(IOException i) 32 { 33 i.printStackTrace(); 34 } 35 } 36 }
反序列化实现Demo:
1 package com.cdh; 2 /** 3 * @author chudonghai 4 * @editor 5 * @date 2019年9月23日 下午2:29:58 6 * @version 7 * @since 8 * @ClassName DeserializationDemo 9 * @Description 反序列化实现Demo 10 */ 11 import java.io.*; 12 13 public class DeserializationDemo 14 { 15 public static void main(String [] args) 16 { 17 Employee e = null; 18 try 19 { 20 FileInputStream fileIn = new FileInputStream("E://aaa//employee.ser"); 21 ObjectInputStream in = new ObjectInputStream(fileIn); 22 e = (Employee) in.readObject(); 23 in.close(); 24 fileIn.close(); 25 }catch(IOException i) 26 { 27 i.printStackTrace(); 28 return; 29 }catch(ClassNotFoundException c) 30 { 31 System.out.println("Employee class not found"); 32 c.printStackTrace(); 33 return; 34 } 35 System.out.println("Deserialized Employee..."); 36 System.out.println("Name: " + e.name); 37 System.out.println("Address: " + e.address); 38 System.out.println("SSN: " + e.SSN); 39 System.out.println("Number: " + e.number); 40 } 41 }
序列化结果:
Serialized data is saved in E:/aaa/employee.ser
反序列化结果:
Deserialized Employee... Name: chudonghai Address: beijing SSN: 0 Number: 101
这里面的Name,Address,Number初始化之后,经过一系列的序列化反序列化,都没有变化,
只有SSN因为注明了transient,没有进行序列化,经过反序列化后,变成了默认值。
- 实现 java.io.Serializable 接口
- 该类的属性必须是可序列化的。如果有一个属性不是可序列化的,则该属性必须注明是短暂的(transient)。只有当前注明transient的属性不被序列化,不影响其他属性的序列化。
readObject使用时需要转换成具体对象。
反序列化时,如果之前的序列化生成的文件找不到了,会报ClassNotFound。