Serializable是java.io包中定义的、用于实现Java类的序列化操作而提供的一个语义级别的接口。Serializable序列化接口没有任何方法或者字段,只是用于标识可序列化的语义。实现了Serializable接口的类可以被ObjectOutputStream转换为字节流,同时也可以通过ObjectInputStream再将其解析为对象。例如,我们可以将序列化对象写入文件后,再次从文件中读取它并反序列化成对象,也就是说,可以使用表示对象及其数据的类型信息和字节在内存中重新创建对象。
因为无论什么编程语言,其底层涉及IO操作的部分还是由操作系统其帮其完成的,而底层IO操作都是以字节流的方式进行的,所以写操作都涉及将编程语言数据类型转换为字节流,而读操作则又涉及将字节流转化为编程语言类型的特定数据类型。而Java作为一门面向对象的编程语言,对象作为其主要数据的类型载体,为了完成对象数据的读写操作,也就需要一种方式来让JVM知道在进行IO操作时如何将对象数据转换为字节流,以及如何将字节流数据转换为特定的对象.
一、序列化实例
①、先定义一个序列化对象User:
- public class User implements Serializable {
- private static final long serialVersionUID = 1L;
- private String userId;
- private String userName;
- public User(String userId, String userName) {
- this.userId = userId;
- this.userName = userName;
- }
- }
②、然后我们编写测试类,来对该对象进行读写操作,我们先测试将该对象写入一个文件:
- public class SerializableTest {
- /**
- * 将User对象作为文本写入磁盘
- */
- public static void writeObj() {
- User user = new User("1001", "Joe");
- try {
- ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("/Users/guanliyuan/user.txt"));
- objectOutputStream.writeObject(user);
- objectOutputStream.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public static void main(String args[]) {
- writeObj();
- }
- }
③、运行上述代码,我们就将User对象及其携带的数据写入了文本user.txt中.
二、反序列化实例
①、将之前持久化写入user.txt文件的对象数据再次转化为Java对象,代码如下:
- public class SerializableTest {
- /**
- * 将类从文本中提取并赋值给内存中的类
- */
- public static void readObj() {
- try {
- ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("/Users/guanliyuan/user.txt"));
- try {
- Object object = objectInputStream.readObject();
- User user = (User) object;
- System.out.println(user);
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public static void main(String args[]) {
- readObj();
- }
- }
②、通过反序列化操作,可以再次将持久化的对象字节流数据通过IO转化为Java对象,结果如下:
- cn.wudimanong.serializable.User@6f496d9f
序列化是指把对象转换为字节序列的过程,我们称之为对象的序列化,就是把内存中的这些对象变成一连串的字节(bytes)描述的过程。
而反序列化则相反,就是把持久化的字节文件数据恢复为对象的过程。那么什么情况下需要序列化呢?大概有这样两类比较常见的场景:1)、需要把内存中的对象状态数据保存到一个文件或者数据库中的时候,这个场景是比较常见的,例如我们利用mybatis框架编写持久层insert对象数据到数据库中时;2)、网络通信时需要用套接字在网络中传送对象时,如我们使用RPC协议进行网络通信时;