1. 序列化是什麼
- 把對象轉換為位元組序列的過程稱為對象的序列化 。
- 把位元組序列恢複為對象的過程稱為對象的反序列化。
2. Java中如何使用序列化
隻需要讓對象實作
Serializable
接口即可,如下:
/**
* @author lirong
* @desc 序列化類
* @date 2019/05/18 12:04
*/
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String name;
public Person(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Person: " +
", id: "+ id +
", name: " + name;
}
}
讓我們來看看
Serializable
接口都幫我們做了什麼工作?
If a serializable class does not explicitly declare a serialVersionUID,
then the serialization runtime will calculate a default
serialVersionUID value for that class based on various aspects of the class,
as described in the Java(TM) Object Serialization Specification.
大緻意思就是:如果沒有為Class顯示的聲明
serialVersionUID
的話,運作時JVM将預設為Class根據Class的各個字段屬性生成一個
serialVersionUID
,具體生成方式就不做研究了,大緻應該是根據各字段的hash值湊成的吧。
3. 測試代碼
3.1 序列化測試類:
/**
* @author lirong
* @desc 序列化測試類
* @since 2019/05/18 12:09
*/
public class SerialTest {
public static void main(String[] args) throws IOException {
Person person = new Person(1234, "Janche");
System.out.println("Person Serial" + person);
FileOutputStream fos = new FileOutputStream("Person.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(person);
oos.flush();
oos.close();
}
}
3.2 反序列化測試類
/**
* @author lirong
* @desc 反序列化測試類
* @date 2019/05/18 12:16
*/
public class DeserialTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream("Person.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Person person = (Person) ois.readObject();
ois.close();
System.out.println("Person Deserial" + person);
}
}
4. 測試條件
a. 不實作
Serializable
接口
b. 實作
Serializable
接口
c. 未自定義
serialVersionUID
字段
d. 自定義
serialVersionUID
字段
e. 反序列化前增加字段
f. 反序列化前減少字段
g. 反序列化前修改字段的類型
說明:反序列化前 表示 在序列化操作完成之後到反序列化開始之前這段時間,更改
類的字段
Person
5. 測試結果
1.隻要有a出現,就會導緻
java.io.NotSerializableException
異常,即無法完成序列化。
2.當條件為 b+c 或者 b+d 時,序列化和反序列化均正常執行。
3.當條件為 b+c+e 或者 b+c+f 時,反序列化時将抛出
InvalidClassException
異常。
4.當條件為 b+d+e 或者 b+d+f 時,序列化和反序列一切正常,增加字段時,反序列化出來該字段為預設值,減少字段時,反序列化出來也将沒有此字段。
5.當條件包含 g 時,反序列化也将抛出
異常。
InvalidClassException
6. 測試總結
1. 盡量為每一個需要序列化的類自定義
serialVersionUID
值,這樣可避免因為Class中字段的修改而帶來的反序列化異常。
2. 盡量不要修改序列化類中的字段類型,如果一定要修改,請重新序列化後再反序列化。
3. 如果要為序列化的類中忽略某個字段,可添加
關鍵字
transient