Java對象序列化
什麼是序列化
概念栗子:
其實也可以這樣理解,相當於快遞的打包和拆包,裏面的東西要保持一致,不能人爲的去改變他,不然就交易不成功。
序列化與反序列化也是一樣,而版本號的存在就是要是裏面內容要是不一致,不然就報錯。像一個防僞碼一樣
什麼是序列化和飯序列化
- 把對象轉換爲字節序列的過程稱爲對象的序列化。
- 把字節序列恢復爲對象的過程稱爲對象的反序列化。
對象的序列化主要有兩種用途:
1.序列化就是將度下個的字節序列永久的保存到硬盤上.通常存放在一個文件中.
2.在網絡上傳送對象的字節序列
在很多應用中,需要對某些對象進行序列化,讓它們離開內存空間,入住物理硬盤,以便長期保存。
比如最常見的是Web服務器中的Session對象,當有 10萬用戶併發訪問,就有可能出現10萬個Session對象,內存可能喫不消,
於是Web容器就會把一些seesion先序列化到硬盤中,等要用了,再把保存在硬盤中的對象還原到內存中。
當兩個進程在進行遠程通信時,彼此可以發送各種類型的數據。無論是何種類型的數據,都會以二進制序列的形式在網絡上傳送。
發送方需要把這個Java對象轉換爲字節序列,才能在網絡上傳送;接收方則需要把字節序列再恢復爲Java對象
java對象序列化爲什麼要使用SerialversionUID
進入源碼
*如果可序列化類未顯式聲明serialVersionUID,則
*序列化運行時將計算默認的serialVersionUID值
*基於類的各個方面的類,如
*Java(TM)對象序列化規範。然而,它是強的
*建議所有可序列化類顯式聲明
*serialVersionUID值,因爲默認的serialVersionUID計算是
*對類細節高度敏感,這些細節可能因編譯器而異
*實現,因此可能導致意外的
*在反序列化過程中<code>InvalidClassException</code>s。因此,爲了
*保證不同java編譯器的serialVersionUID值一致
*實現時,可序列化類必須聲明顯式
*serialVersionUID值。同時強烈建議
*serialVersionUID聲明使用<code>private</code>修飾符,其中
*可能,因爲這樣的聲明只適用於立即聲明
*類——serialVersionUID字段作爲繼承成員不有用。陣列
*類不能聲明顯式的serialVersionUID,因此它們總是
*默認計算值,但需要匹配
*數組類放棄serialVersionUID值。
如果可序列化類未顯式聲明serialVersionUID,則序列化運行時將計算默認的serialVersionUID值.
但如果使用了默認的serialVersionUID值.則修改了實體類的時候,實體類對象的serialVersionUID值也會改變,當你反序列化的時候,比較serialVersionUID值不一致,就拋出InvalidClassException異常
如何進行序列化
- 需要做序列化的對象的類,必須實現序列化接口:Java.lang.Serializable 接口(這是一個標誌接口,沒有任何抽象方法),Java 中大多數類都實現了該接口,比如:String,Integer
- 底層會判斷,如果當前對象是 Serializable 的實例,才允許做序列化,Java對象 instanceof Serializable 來判斷。
- 在 Java 中使用對象流來完成序列化和反序列化
ObjectOutputStream:通過 writeObject()方法做序列化操作
ObjectInputStream:通過 readObject() 方法做反序列化操作
Person 類(get set省略)
@Data
public class Person implements Serializable {
private static final long serialVersionUID = -5809782578272943999L;
private int age;
private String name;
private String sex;
private String address;
TestPersonSerialize 測試類
public class TestPersonSerialize {
public static void main(String[] args) throws Exception {
serializePerson();
Person p = deserializePerson();
System.out.println(p.getName()+";"+p.getAge());
}
private static void serializePerson() throws FileNotFoundException,IOException {
Person person = new Person();
person.setName("測試實例");
person.setAge(25);
person.setSex("male");
ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(
new File("E:/person.txt")));
oo.writeObject(person);
System.out.println("序列化成功");
oo.close();
}
private static Person deserializePerson() throws IOException, Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("E:/person.txt")));
Person person = (Person) ois.readObject();
System.out.println("反序列化成功");
return person;
}
}