序列化和反序列化的概念
序列化:把对象转换为字节序列的过程称为对象的序列化。
反序列化:把字节序列恢复为对象的过程称为对象的反序列化。
什么情况下需要序列化
当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
当你想用套接字在网络上传送对象的时候;
当你想通过RMI传输对象的时候;
如何实现序列化
实现Serializable接口即可
注意事项
- 在默认的序列化实现中,会包括 非静态域 和 非瞬时域,与域的可见性声明没有关系,可能导致隐私信息泄露。
- 与1相对,静态域和瞬时域不会被序列化。
- 添加
serialVersionUID
private static final long serialVersionUID = 1L;
序列化运行时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联,该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。如果接收者加载的该对象的类的 serialVersionUID 与对应的发送者的类的版本号不同,则反序列化将会导致 InvalidClassException。可序列化类可以通过声明名为 "serialVersionUID" 的字段(该字段必须是静态 (static)、最终 (final) 的 long 型字段)显式声明其自己的 serialVersionUID.
经试验,序列化前后类的定义发生了变化,但是serialVersionUID不变的时候,仍是可以反序列化成功的。但是即使类定义没有发生任何改动,只是动了serialVersionUID,反序列化也会失败。
public class SerializeTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// MySerialize ms = new MySerialize(28, "nan", "bmw");
// ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myobj.txt"));
// oos.writeObject(ms);
// oos.flush();
// oos.close();
// MySerialize.age = 11;
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myobj.txt"));
MySerialize msnew = (MySerialize) ois.readObject();
ois.close();
System.out.println(msnew.toString());
}
}
class MySerialize implements Serializable {
public static final long serialVersionUID = 1L;
// static int age;
String name;
String car;
public MySerialize(int age, String name, String car) {
// this.age = age;
this.name = name;
this.car = car;
}
@Override
public String toString() {
return this.name + this.car;
}
}