欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java自定義序列化的具體使用

 更新時間:2021年11月15日 15:14:42   作者:寫不完作業(yè)還要玩  
本文主要介紹了java自定義序列化的具體使用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

1.問題引出

在某些情況下,我們可能不想對于一個對象的所有field進行序列化,例如我們銀行信息中的設計賬戶信息的field,我們不需要進行序列化,或者有些field本省就沒有實現(xiàn)Serializable接口。

java中的序列化是遞歸序列化,也就是你的field的引用類型中也有field可以被序列化,那么就會在序列化當前對象的時候,一同序列化

2.解決辦法

使用transient(瞬變現(xiàn)象;過往旅客;候鳥)關鍵字來修飾,該關鍵字只能修飾屬性,這樣在序列化的時候,這個屬性就會用默認值,例如int類型用0,引用對象用null;

但是使用transient關鍵字修飾的field雖然簡單方便,但是會被完全隔離在序列化機制之外,這樣導致在反序列化回復java對象的時候,無法取得該field的值。

因此我們可以使用自定義序列化機制,可以讓程序控制如何序列化各field,甚至完全不序列化某些field(這樣就與transient相同),在序列化和反序列化過程中需要特殊處理的類應該提供如下特殊簽名的方法,這些特殊的方法用以實現(xiàn)自定義的序列化

private void writeObject(java.io.ObjectOutputStream out) throws IOException;
private void readObject(java.io.ObjectInputStream in)throws IOException,ClassNotFoundException;
private void readObejctNoData()throws ObejctStreamException;

熱愛你所寫的每一行的代碼

writeObject()方法負責寫入特定類的實例狀態(tài),通過重寫這個方法,程序員可以完全獲得對序列化機制的控制,可以自主決定那些field需要序列化,需要怎么序列化,默認情況(函數(shù)體為空)該方法會調用out.defaultWriteObject來保存java對象的各field,從而達到實現(xiàn)序列化java對象狀態(tài)的目的

readObject負責從流中讀取并且回復對象的field,通過重寫該方法,程序員,可以獲得對反序列化機制的控制,對于反序列化各個field的順序應該和序列化各個field的順序相同。

至于當序列化流不完整時,readObjectNoData可以正確的初始化反序列化的對象,例如接收方接收到的序列化流殘缺,或者序列化版本不同,則使用readObjectNoData來默認的初始化。

例子(對于person的改寫):

class Person implements Serializable
{
 private String name;
 private int age;
 public Person(String name,int age)
 {
  this.name=name;
  this.age=age;
 }
 //自動生成的Get和Set方法
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
 private void writeObject(ObjectOutputStream out) throws IOException
 {
  //將名字翻轉之后寫入二進制流
  out.writeObject(new StringBuffer(this.name).reverse());
  out.writeInt(this.age);
 }
 private void readObject(ObjectInputStream in)throws IOException,ClassNotFoundException
 {
  this.name=((StringBuffer)in.readObject()).reverse().toString();
  //會拋出異常,因為這里的這樣寫法導致同
  this.age=in.readInt();
 }
}

應該提醒的是,這個自定義的功能十分強大

另外一種替換性的改寫:

//注意:這個方法由序列化機制調用,只要該方法存在就,它的訪問控制符就可以為private protected package-private中的任意一種
 private Object writeReplace() throws ObjectStreamException
 {
  ArrayList<Object> list=new ArrayList<>();
  list.add(name);
  list.add(age);
  //我們這里返回ArrayList
  return list;
 }

序列化機制保證在序列化某個對象之前,先調用該對象的writeReplace方法,如果該方法返回另外一個java對象,系統(tǒng)就轉換為序列化writeReplace的返回結果。(ps:如果這個返回結果也有writeReplace方法的話,就繼續(xù)遞歸替代,直到沒有替換)

相應與writeReplace相對的有一個readResolve方法,這個方法保護性的賦值整個對象,這里就不展開討論了。

3.另外一種自定義序列化機制(介紹Externalizable)

Java還提供了另一種序列化機制,這種序列化方式完全由程序員決定存儲和恢復對象數(shù)據。要實現(xiàn)該目標,Java類必須實現(xiàn)Externalizable接口,該接口里定義了如下兩個方法。

  • void readExternal(ObjectInput in):需要序列化的類實現(xiàn)readExternal()方法來實現(xiàn)反序列化。該方法調用DataInput(它是ObjectInput的父接口)的方法來恢復基本類型的Field值,調用ObjectInput的readObject()方法來恢復引用類型的Field值。
  • void writeExternal(ObjectOutput out):需要序列化的類實現(xiàn)writeExternal()方法來保存對象的狀態(tài)。該方法調用DataOutput(它是ObjectOutput的父接口)的方法來保存基本類型的Field值,調用ObjectOutput的writeObject()方法來保存引用類型的Field值。

具體的實現(xiàn)方式與上面自定義Serializable接口的實現(xiàn)類的序列化是相同的操作,這里就不闡述了,下面圖是二者的比較。

到此這篇關于java自定義序列化的具體使用的文章就介紹到這了,更多相關java自定義序列化內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論