序列化:將堆內(nèi)存中的Java對象,轉(zhuǎn)換成字節(jié)序列,使其支持持久化存儲(存儲到磁盤)和網(wǎng)絡(luò)傳輸
反序列化:將字節(jié)序列恢復(fù)成成Java 對象(需要Java 對象的 .class文件)
1. 實(shí)現(xiàn) Serializable 接口
要想實(shí)現(xiàn)序列化,必須實(shí)現(xiàn) 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)不希望序列化后在網(wǎng)絡(luò)中傳輸,可以添加 transient
屬性,表明該字段不會被序列化。
4. Java 類中定義的 static 字段不會被序列化
public class Student implements Serializable {
private static String school = "中科大";
...
}
序列化時,會忽略static 修飾的字段school,但是進(jìn)行反序列化時,仍然可以取出該對象的school 值為 “中科大”,該數(shù)據(jù)并不是從序列化二進(jìn)制數(shù)據(jù)中所得,而是從 JVM 中得到。
5. 序列化版本問題:serialVersionUID
如果Java 對象中沒有指定 serialVersionUID 的值,則該值會自動根據(jù)對象中的屬性計(jì)算賦值,即屬性改變后 serialVersionUID 也會改變。
這樣就可能導(dǎo)致序列化版本不一致問題:在完成序列化操作后,生成初始 serialVersionUID
,.class
和 序列化二進(jìn)制數(shù)據(jù)均可計(jì)算出該相同的serialVersionUID
。
由于項(xiàng)目的升級或修改,可能我們會對序列化對象進(jìn)行修改,比如增加某個字段,.class
文件改變。那么我們在進(jìn)行反序列化時根據(jù).class
計(jì)算得到的時 new serialVersionUID
,而根據(jù)序列化生成的二進(jìn)制數(shù)據(jù)得到的是 初始 serialVersionUID
,不一致,就會報(bào)錯。
解決:為每個序列化的對象手動指定serialVersionUID
private static final long serialVersionUID = 987884045085285050L;
‘