序列化:将堆内存中的Java对象,转换成字节序列,使其支持持久化存储(存储到磁盘)和网络传输
反序列化:将字节序列恢复成成Java 对象(需要Java 对象的 .class文件)
1. 实现 Serializable 接口
要想实现序列化,必须实现 Serializable
接口
public class Student implements Serializable {
private static final long serialVersionUID = 987884045085285050L;
private static String school = "中科大";
private int age;
private String name;
private transient Double height=12.32;
}
2. 使用 ObjectOutputStream
ObjectInputStream
存储读取Java对象
public static void main(String[] args) {
Student student = new Student();
student.setAge(12);
student.setHeight(182.00);
student.setName("张三");
ObjectOutputStream outputStream = new
ObjectOutputStream(new FileOutputStream("a.txt"));
outputStream.writeObject(student);
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("a.txt"));
Student student = (Student) inputStream.readObject();
System.out.println(student);
}
3. 某些隐私字段不想序列化:transient
如果Java对象中的某些隐私字段(例中的 height)不希望序列化后在网络中传输,可以添加 transient
属性,表明该字段不会被序列化。
4. Java 类中定义的 static 字段不会被序列化
public class Student implements Serializable {
private static String school = "中科大";
...
}
序列化时,会忽略static 修饰的字段school,但是进行反序列化时,仍然可以取出该对象的school 值为 “中科大”,该数据并不是从序列化二进制数据中所得,而是从 JVM 中得到。
5. 序列化版本问题:serialVersionUID
如果Java 对象中没有指定 serialVersionUID 的值,则该值会自动根据对象中的属性计算赋值,即属性改变后 serialVersionUID 也会改变。
这样就可能导致序列化版本不一致问题:在完成序列化操作后,生成初始 serialVersionUID
,.class
和 序列化二进制数据均可计算出该相同的serialVersionUID
。
由于项目的升级或修改,可能我们会对序列化对象进行修改,比如增加某个字段,.class
文件改变。那么我们在进行反序列化时根据.class
计算得到的时 new serialVersionUID
,而根据序列化生成的二进制数据得到的是 初始 serialVersionUID
,不一致,就会报错。
解决:为每个序列化的对象手动指定serialVersionUID
private static final long serialVersionUID = 987884045085285050L;
‘