序列化的方式以及序列化可能產生的異常
為什麼要序列化?
有的時候我們想把一個java物件變成位元組流的形式進行傳輸(序列化),或者把一個位元組流變成物件(反序列化)
序列化常用的兩種方式:
1️⃣ 實現Serializable介面,也是經常使用的方式,用法很簡單,只需要在需要序列化的實體類上加上implements Serializable即可,這個介面是一個空的介面,它的主要作用是標識這個物件是可序列化的物件.
物件的個別屬性如果不想被序列化可以在類中加上transient關鍵字
publicclass Article implements java.io.Serializable {
privatestaticfinallong
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 做個對比