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异常