天天看點

Java程式設計思想之 ----- 序列化和反序列化一、入門二、如何實作三、了解四、源碼解析

一、入門

首先當然得了解什麼是序列化和反序列化

  • 序列化是将Java對象序列化成二進制(即位元組序列)的過程。
  • 反序列是将被位元組序列重新變成Java對象的過程。
了解:本質上是改變了Java對象的生存周期,使得Java對象可以持久化存儲,同時也實作了對象也可以作為網絡傳輸的資料。

二、如何實作

通過繼承 Serializable 接口便可實作對象的序列化。

Java程式設計思想之 ----- 序列化和反序列化一、入門二、如何實作三、了解四、源碼解析
挖坑:檢視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語言僅有的特性去了解,這其實就是一種解決對象存儲問題的實作機制。

四、源碼解析

看了網上有不少源碼解析的文章,就不特地寫了

源碼分析(一)

源碼分析(二)