Java 的序列化就是将一个 Java 对象转化为一个字节流的一种机制。从字节流再转回 Java 对象叫做反序列化,是序列化的反向操作。
序列化和反序列化是和平台无关的,也就是说你可以在 Linux 系统序列化,然后在 Windows 操作系统做反序列化。
如果要序列化对象,需要使用 ObjectOutputStream 类的 writeObject() 方法。如果要做反序列化,则要使用 ObjectOutputStream 类的 readObject() 方法。
如下图所示,对象被转化为字节流后,被储存在了不同的介质中。这个流程就是序列化。在图的右边,也可以看到从不同的介质中,比如内存,获得字节流并转化为对象,这叫做反序列化。
如果我们创建了一个 Java 对象,这个对象的状态在程序执行完毕或者退出后就消失了,不会得到保存。
所以,为了能解决这类问题,Java 提供了序列化机制。这样,我们就能把对象的状态做临时储存或者进行持久化,以供后续当我们需要这个对象时,可以通过反序列化把对象还原回来。
下面给出一些代码看看我们是怎么来做序列化的。
import java.io.Serializable; public class Player implements Serializable { private static final long serialVersionUID = 1L; private String serializeValueName; private transient String nonSerializeValuePos; public String getSerializeValueName() { return serializeValueName; } public void setSerializeValueName(String serializeValueName) { this.serializeValueName = serializeValueName; } public String getNonSerializeValueSalary() { return nonSerializeValuePos; } public void setNonSerializeValuePos(String nonSerializeValuePos) { this.nonSerializeValuePos = nonSerializeValuePos; } @Override public String toString() { return "Player [serializeValueName=" + serializeValueName + "]"; } }
import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; public class SerializingObject { public static void main(String[] args) { Player playerOutput = null; FileOutputStream fos = null; ObjectOutputStream oos = null; playerOutput = new Player(); playerOutput.setSerializeValueName("niubi"); playerOutput.setNonSerializeValuePos("x:1000,y:1000"); try { fos = new FileOutputStream("Player.ser"); oos = new ObjectOutputStream(fos); oos.writeObject(playerOutput); System.out.println("序列化数据被存放至Player.ser文件"); oos.close(); fos.close(); } catch (IOException e) { e.printStackTrace(); } } }
Output:
序列化数据被存放至Player.ser文件
import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream; public class DeSerializingObject { public static void main(String[] args) { Player playerInput = null; FileInputStream fis = null; ObjectInputStream ois = null; try { fis = new FileInputStream("Player.ser"); ois = new ObjectInputStream(fis); playerInput = (Player) ois.readObject(); System.out.println("从Player.ser文件中恢复"); ois.close(); fis.close(); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } System.out.println("player名字为 : " + playerInput.getSerializeValueName()); System.out.println("player位置为 : " + playerInput.getNonSerializeValuePos()); } }
Output:
从Player.ser文件中恢复 player名字为 : niubi player位置为 : null