一、入門
首先當然得理解什麼是序列化和反序列化
- 序列化是將Java對象序列化成二進制(即字節序列)的過程。
- 反序列是將被字節序列重新變成Java對象的過程。
理解:本質上是改變了Java對象的生存週期,使得Java對象可以持久化存儲,同時也實現了對象也可以作爲網絡傳輸的數據。
二、如何實現
通過繼承 Serializable 接口便可實現對象的序列化。
挖坑:查看Serializable 接口可以看到是空實現,具體作用下面講解
怎麼實現直接上代碼(ps:例子是抄的附上鍊接 序列化和反序列化的底層實現原理是什麼)
public class SerialDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//序列化
FileOutputStream fos = new FileOutputStream("object.out");
ObjectOutputStream oos = new ObjectOutputStream(fos);
User user1 = new User("xuliugen", "123456", "male");
oos.writeObject(user1);
oos.flush();
oos.close();
//反序列化
FileInputStream fis = new FileInputStream("object.out");
ObjectInputStream ois = new ObjectInputStream(fis);
User user2 = (User) ois.readObject();
System.out.println(user2.getUserName()+ " " +
user2.getPassword() + " " + user2.getSex());
//反序列化的輸出結果爲:xuliugen 123456 male
}
}
public class User implements Serializable {
public static final long serialVersionUID = 42L;
private String userName;
private String password;
private String sex;
//全參構造方法、get和set方法省略
}
注意
- static和transient修飾的屬性不能被序列化
理解:
static修飾的屬性值是存儲在當前JVM中的
transient是因爲這個關鍵字的特性就是防止一些屬性被序列化,因爲有一些敏感信息不想被別人訪問(比如密碼,你要是持久化對象了,別人就能讀到你的密碼了!)
- 還有一個需要注意的點是那個大家都說的serialVersionUID
理解:
序列化時使用一個稱爲 serialVersionUID 的版本號與每個可序列化類相關聯,該序列號用在反序列化過程中,驗證這個字節序列是否能夠被轉化的對象所兼容。(簡單來說,就是如果反序列時定義的類的serialVersionUID和序列化時的類定義的serialVersionUID不一樣,就不能被反序列。)
爲它賦予明確的值。顯式地定義serialVersionUID有兩種用途:
1.在某些場合,希望類的不同版本對序列化兼容,因此需要確保類的不同版本具有相同的serialVersionUID;
2.在某些場合,不希望類的不同版本對序列化兼容,因此需要確保類的不同版本具有不同的serialVersionUID。
三、理解
如前所述,序列化和反序列化本質上是改變了Java對象的生存週期,使得Java對象可以持久化存儲,同時也實現了對象也可以作爲網絡傳輸的數據。
所以,在理解序列化和反序列化的時候,不應該將它作爲Java語言僅有的特性去理解,這其實就是一種解決對象存儲問題的實現機制。