1. 程式人生 > >序列化的方式以及序列化可能產生的異常

序列化的方式以及序列化可能產生的異常

為什麼要序列化?

  有的時候我們想把一個java物件變成位元組流的形式進行傳輸(序列化),或者把一個位元組流變成物件(反序列化)

序列化常用的兩種方式:

  1️⃣  實現Serializable介面,也是經常使用的方式,用法很簡單,只需要在需要序列化的實體類上加上implements Serializable即可,這個介面是一個空的介面,它的主要作用是標識這個物件是可序列化的物件.

物件的個別屬性如果不想被序列化可以在類中加上transient關鍵字

publicclass Article implements java.io.Serializable {

privatestaticfinallong

serialVersionUID = 1L;

private Integer id; private String title; //文章標題

  2️⃣  實現Externalizable,實際該介面是繼承了Serializable介面,不同的是實現該介面要覆蓋兩個方法

/*** 序列化操作的擴充套件類 */

@Override

publicvoidwriteExternal(ObjectOutput out) throws IOException {

//增加一個新的物件

Date date=new Date();

out.writeObject(userName);

out.writeObject(password);

out.writeObject(date);

}

/*** 反序列化的擴充套件類 */

@Override

publicvoidreadExternal(ObjectInput in) throws IOException,ClassNotFoundException {

//注意這裡的接受順序是有限制的哦,否則的話會出錯的

// 例如上面先write的是A物件的話,那麼下面先接受的也一定是A物件...

userName=(String) in.readObject();

password=(String) in.readObject();

SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");

Date date=(Date)in.readObject();

System.out.println("反序列化後的日期為:"+sdf.format(date));

}

重點:序列化時出現的錯誤

如果沒有明確指定serialVersionUID,序列化的時候會根據欄位和特定的演算法生成一個serialVersionUID,當屬性有變化時這個id發生了變化,所以反序列化的時候 

就會失敗。丟擲“本地classd的唯一id和流中class的唯一id不匹配”。

解決方法實際也很簡單,只需要在實體類中自己定義一個

privatestaticfinallong serialVersionUID = 1L;就可以了

在這想再插一句,其實實現序列化的方式還有,有興趣的可以瞭解一下.

3️⃣  把物件包裝成JSON字串傳輸 ,這裡採用JSON格式,同時採用Google的gson-2.2.2.jar進行轉義

4️⃣  採用谷歌的ProtoBuf,

隨著Google工具protoBuf的開源,protobuf也是個不錯的選擇。對JSON,Object Serialize(Java的序列化和反序列化), ProtoBuf 做個對比