记录对Serializable序列化接口的理解

181 阅读2分钟

Serializable由java.io包中定义,接口中没有任何方法或者字段,只是用来标识可序列化.实现了Serializable接口的类可以被ObjectOutputStream转换为字节流,同时也可以通过ObjectInputStream再将其解析为对象.这也就是说,可以使用表示对象及其数据类型信息和字节在内存中重新创建对象。 而这一点对于面向对象编程语言来说是非常重要的,因为无论什么编程语言,其底层涉及到io操作的部分还是由操作系统帮其完成的。而底层的io操作都是以字节流的方式进行的。所以写操作都涉及将编程语言数据类型转换为字节流(序列化),而读操作则又涉及到将字节流转化为编程语言类型的特定数据类型(反序列化)。在java中,就是通过Serializable接口来承担数据读写转换的角色。

//==测试代码==
public class User implements Serializable {//序列化一个对象
    private static final long serialVersionUID = -8098023240824642621L;
    private String userId;
    private String userName;

    public User(String userId, String userName) {
        this.userId = userId;
        this.userName = userName;
    }

    @Override
    public String toString() {
        return "User{" +
                "userId='" + userId + '\'' +
                ", 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 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[]) { 
        writeObj(); 
        readObj(); 
    } 
} 
序列化与反序列化

序列化:就是把对象转换为字节序列的过程(对象的序列化)

序列化使用场景:(1)利用mybatis框架编写持久层insert对象数据到数据库中 (2)网络通信时需要用套接字在网络中传送对象时,比如用RPC协议进行网络通信

反序列化:就是把持久化的字节文件数据恢复为对象的过程。

serialVersionUID

对于JVM来说,要进行持久化的类必须要有一个标记,只有持有这个标记JVM才允许类创建的对象可以通过io系统将其转换为字节数据,从而实现持久化。而这个标记就是Serializable接口。而在反序列化的过程中则需要使用serialVersionUID来确定由那个类来加载这个对象,所以在实现Serializable接口的时候,需要显示的定义serialVersionUID。如果反序列化的serialVersionUID和序列化时的serialVersionUID不一致就会导致InvalidClassException异常