
Java 將創建出來的物件,存放在 JVM 的對記憶體中,只有在 JVM 運行的時候,這些物件才會存在,一旦 JVM 停止運行,這些物件的狀態也就隨之消失了,
但是在一些應用場景中,我們需要將這些物件進行持久化,并且需要在使用的時候能夠重新讀取物件資訊,比如說在 RPC 呼叫的時候,需要將物件通過網路進行傳輸,此時就需要下將物件記性序列化進行傳輸,再將其反序列化進行處理,
序列化(Serialization)是指將物件的狀態資訊,轉換成可以可以存盤或傳輸的形式,在網路傳輸程序中,可以是位元組或是XML等格式,
- 序列化:Java物件轉換為位元組序列,
- 反序列化:位元組序列恢復為原先的Java物件,
Java 提供了一種物件序列化的機制,用一個位元組序列可以表示一個物件,該位元組序列包含該物件的資料、物件的型別和物件中存盤的屬性等資訊,位元組序列寫出到檔案之后,相當于檔案中持久保存了一個物件的資訊,
反之,該位元組序列還可以從檔案中讀取回來,重構物件,對它進行反序列化,物件的資料、物件的型別和物件中存盤的資料資訊,都可以用來在記憶體中創建物件,
Java提供了下面這些類來進行序列化和反序列化
java.io.Serializable
java.io.Externalizable
ObjectOutput
ObjectInput
ObjectOutputStream
ObjectInputStream
Serializable 介面
java.io.Serializable 是一個沒有任何方法或者欄位的介面類,僅用于標識這個類可以被序列化,如果要序列化的類有父類,要想同時將在父類中定義過的變數持久化下來,那么父類也應該集成 java.io.Serializable 介面,
Java在進行序列化之前,會檢查類是否實作了Serializable介面,沒有實作就會報Serializable 介面就會報 NotSerializableException 例外,

往序列化的方法底層看到 java.io.ObjectOutputStream#writeObject0 介面,它對被序列化物件的型別進行了判斷,不是字串、陣列、列舉,也沒有實作 Serializable 的介面都會拋出 NotSerializableException 例外,

Externalizable 介面
Externalizable繼承了Serializable,該介面中定義了兩個抽象方法:writeExternal()與readExternal(),當使用Externalizable介面來進行序列化與反序列化的時候需要開發人員重寫writeExternal()與readExternal()方法,
serialVersionUID 的作用
反序列化的時候可能遇到 InvalidClassException 例外,說是序列化的時候位元組碼檔案的 serialVersionUID 和本地類的 serialVersionUID 不一致,這是由于反序列化的時候對類進行了修改,比如加上一個 toString 方法列印物件資訊,
使用 ObjectOutputStream、ObjectInputStream 進行序列化
public void serialize() {
User user = new User("深頁", 18, "杭州");
try (
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.txt"));
) {
oos.writeObject(user);
System.out.println("Serialized data is saved");
} catch (IOException e) {
e.printStackTrace();
}
}
public void deserialize() {
try (
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.txt"));
) {
User user = (User) ois.readObject();
System.out.println(user);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
static、transient 修飾不想被序列化的變數
被 static 和 transient 修飾的欄位是不會被序列化的:
- 序列化保存的是物件的狀態而非類的狀態,所以會忽略 static 靜態域;
- 序列化某個類的物件時,不希望某個欄位被序列化,可以用 transient 修飾變數
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/160757.html
標籤:Java
上一篇:JSON是什么,為什么這么流行?
