序列化與反序列化的簡單粗暴解釋
一、內容簡介
1.什麽是序列化和反序列化?
(1)序列化就是把Java對象轉化為字節流序列(二進制串)的過程
(2)反序列化就是把字節流(二進制串)恢復為Java對象的過程
2.為什麽要進行序列化
我們知道,當兩個進程需要通信的時候,可以發送各種類型的數據,包括文字、圖片、音頻和視頻,但是這些數據都是以二進制的形式在網絡上傳輸。所以當兩個Java進程進行通信的時候,如何實現進程間對象的傳送呢。這就需要用到序列化和反序列化了。一方面,發送方將這個Java對象轉化為字節對象,然後在網絡上傳輸。另一個方面,接收方需要從字節序列中恢復出Java對象。
3.好處
第一.利用序列化實現遠程的通信,即在網絡上傳輸信息。第二,可以實現數據的持久化,通過序列化可以把數據永久的保存到硬盤上。
二、Java類庫中的序列化
Java.io.ObjectOutputStream代表對象輸出流,它的WriteObject( object obj) 方法可以對指定的obj對象進行序列化,把得到的二進制串輸入到指定的文件中。
與此相對應,Java.io.ObjectInputStream代表對象輸入流,它的readObject(object obj)方法可以將讀取的二進制串進行反序列化為Java對象,並且將其返回。
只有實現了Serializable接口的類才能夠被序列化,所以一定要實現Serializable。跳進去你會發現,只有一個Serializable接口。
- <span style="font-family:KaiTi_GB2312;font-size:18px;"> * @author unascribed
- * @version 1.25, 11/17/05
- * @see java.io.ObjectOutputStream
- * @see java.io.ObjectInputStream
- * @see java.io.ObjectOutput
- * @see java.io.ObjectInput
-
* @see java.io.Externalizable
- * @since JDK1.1
- */
- public interface Serializable {
- }</span>
2.對象序列化的步驟如下
(1)創建對象輸入流,它可以包裝一個其他類型的目標輸入流,例如:文件輸出流。
(2)通過對象輸入流的writeObject()方法寫對象。
3.對象的反序列化如下:
(1)創建對象輸入流,同樣的,可以包含其他類型的目標輸出流,例如:文件輸入流。
(2)通過對象輸入流的readObject()方法讀取對象。
4.實例
(1)創建User對象
[java] view plain copy- <span style="font-family:KaiTi_GB2312;font-size:18px;">/**
- * 用戶
- * @author lizhenjuan
- */
- public class User implements java.io.Serializable{
- private static final long serialVersionUID = 1L;
- private Long id;
- private String name; // 真實姓名
- private String loginName; // 登錄名
- private String description; // 說明
- }
- </span>
(2)序列化Use對象
- <span style="font-family:KaiTi_GB2312;font-size:18px;"> /**
- * User對象序列化測試代碼
- * @throws FileNotFoundException
- * @throws IOException
- */
- @Test
- private static void SerializablePerson() throws Exception, FileNotFoundException, IOException{
- User user = new User();
- user.setName("lizhenjuan");
- user.setLoginName("lzh");
- user.setDescription("just test");
- //輸出流,將對象輸出到txt文件中
- ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(new File("F:/User.txt")));
- oo.writeObject(user);
- System.out.println("序列化成功!");
- oo.close();
- }</span>
執行結果,是在F 盤下生成了User.txt文件。
(3)反序列化User對象
[java] view plain copy
- <span style="font-family:KaiTi_GB2312;font-size:18px;">/**
- * 反序列化User對象,對去User.txt文件內容
- * @return
- * @throws Exception
- * @throws FileNotFoundException
- * @throws IOException
- * @throws ClassNotFoundException
- */
- private static User DeserializePerson() throws Exception,FileNotFoundException, IOException, ClassNotFoundException {
- ObjectInputStream ois=new ObjectInputStream(new FileInputStream(new File("F:/User.txt")));
- User user =(User)ois.readObject();
- System.out.println("User對象反序列化成功");
- return user;
- }
- //讀取User.txt文件的內容
- public static void main(String[] args) throws Exception{
- User user = DeserializePerson(); //反序列化對象
- System.out.println(MessageFormat.format("name={0},loginName={1},description={2}",
- user.getName(),user.getLoginName(),user.getDescription()));
- }
- </span>
讀取F盤User.txt文件內容,打印出來。
打印內容如下:
三、SerialVersionUID 的作用
1.兩種類型
SerialVersionUID:意思是序列化的版本號,凡是實現序列化接口的類都會有一個表示序列化版本標識的靜態變量。
SerialVersionUID的兩種生成方式。
第一種
采用這種方式生成的SerialVersionUID是1L;
private static final long serialVersionUID = 1L;
第二種
這一種是根據類名稱、接口名稱、方法和屬性來生成的。
private static final long serialVersionUID = 4603642343377807741L;
2.SerialVersionID作用是什麽?
SerialVerssionID
保證在很多類中,某個類的編號是唯一的。如果在實體類中,沒有顯式聲明SerialVersionID,那麽java編譯器會自動給你生成一個ID。如果要在序列化之後的實體中添加一個字段,那麽序列化之後,就又會生成一個SerialVersionID
,於是就會出現兩個序列化版本號不一致的錯誤。所以,我們在類中顯式聲明樂SerialVersionUID之後,就可以在序列化之後,增加或者刪除一個字段,而不會影響到後期的還原。還原之後,可以使用。
類的serialVersionUID的默認值完全依賴於Java編譯器的實現,對於同一個類,用不同的Java編譯器編譯,有可能會導致不同的
serialVersionUID,也有可能相同。為了提高serialVersionUID的獨立性和確定性,強烈建議在一個可序列化類中顯示的定義serialVersionUID,為它賦予明確的值。
序列化與反序列化的簡單粗暴解釋