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

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

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

1.問題引出

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

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

2.解決辦法

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

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

因此我們可以使用自定義序列化機(jī)制,可以讓程序控制如何序列化各field,甚至完全不序列化某些field(這樣就與transient相同),在序列化和反序列化過程中需要特殊處理的類應(yīng)該提供如下特殊簽名的方法,這些特殊的方法用以實現(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()方法負(fù)責(zé)寫入特定類的實例狀態(tài),通過重寫這個方法,程序員可以完全獲得對序列化機(jī)制的控制,可以自主決定那些field需要序列化,需要怎么序列化,默認(rèn)情況(函數(shù)體為空)該方法會調(diào)用out.defaultWriteObject來保存java對象的各field,從而達(dá)到實現(xiàn)序列化java對象狀態(tài)的目的

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

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

例子(對于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
 {
  //將名字翻轉(zhuǎn)之后寫入二進(jìn)制流
  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();
  //會拋出異常,因為這里的這樣寫法導(dǎo)致同
  this.age=in.readInt();
 }
}

應(yīng)該提醒的是,這個自定義的功能十分強(qiáng)大

另外一種替換性的改寫:

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

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

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

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

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

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

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

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

相關(guān)文章

  • java連接MySQl數(shù)據(jù)庫實例代碼

    java連接MySQl數(shù)據(jù)庫實例代碼

    這篇文章介紹了java連接MySQl數(shù)據(jù)庫實例代碼,有需要的朋友可以參考一下
    2013-10-10
  • java中ThreadLocal的基本原理

    java中ThreadLocal的基本原理

    本文講解了java中ThreadLocal的一些基本原理,文中關(guān)于ThreadLocal的原理講解的非常詳細(xì),感興趣的朋友一起看看吧
    2021-08-08
  • Spring Boot Actuator未授權(quán)訪問漏洞的問題解決

    Spring Boot Actuator未授權(quán)訪問漏洞的問題解決

    Spring Boot Actuator 端點(diǎn)的未授權(quán)訪問漏洞是一個安全性問題,可能會導(dǎo)致未經(jīng)授權(quán)的用戶訪問敏感的應(yīng)用程序信息,本文就來介紹一下解決方法,感興趣的可以了解一下
    2023-09-09
  • Java中request對象常用方法匯總

    Java中request對象常用方法匯總

    這篇文章主要為大家詳細(xì)匯總了Java中request對象的常用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • SpringBoot實現(xiàn)動態(tài)增刪啟停定時任務(wù)的方式

    SpringBoot實現(xiàn)動態(tài)增刪啟停定時任務(wù)的方式

    在spring?boot中,可以通過@EnableScheduling注解和@Scheduled注解實現(xiàn)定時任務(wù),也可以通過SchedulingConfigurer接口來實現(xiàn)定時任務(wù),但是這兩種方式不能動態(tài)添加、刪除、啟動、停止任務(wù),本文給大家介紹SpringBoot實現(xiàn)動態(tài)增刪啟停定時任務(wù)的方式,感興趣的朋友一起看看吧
    2024-03-03
  • mybatis查詢實現(xiàn)返回List<Map>類型數(shù)據(jù)操作

    mybatis查詢實現(xiàn)返回List<Map>類型數(shù)據(jù)操作

    這篇文章主要介紹了mybatis查詢實現(xiàn)返回List<Map>類型數(shù)據(jù)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Java郵件發(fā)送程序(可以同時發(fā)給多個地址、可以帶附件)

    Java郵件發(fā)送程序(可以同時發(fā)給多個地址、可以帶附件)

    不錯的功能比較齊全的郵件發(fā)送程序源碼
    2008-07-07
  • SpringBoot詳解整合Spring?Boot?Admin實現(xiàn)監(jiān)控功能

    SpringBoot詳解整合Spring?Boot?Admin實現(xiàn)監(jiān)控功能

    這篇文章主要介紹了SpringBoot整合Spring?Boot?Admin實現(xiàn)服務(wù)監(jiān)控,內(nèi)容包括Server端服務(wù)開發(fā),Client端服務(wù)開發(fā)其中Spring?Boot?Admin還可以對其監(jiān)控的服務(wù)提供告警功能,如服務(wù)宕機(jī)時,可以及時以郵件方式通知運(yùn)維人員,感興趣的朋友跟隨小編一起看看吧
    2022-07-07
  • SpringBoot+docker環(huán)境變量配置詳解

    SpringBoot+docker環(huán)境變量配置詳解

    這篇文章主要介紹了SpringBoot+docker環(huán)境變量配置詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • 一文揭曉如何在Java中終止一個線程

    一文揭曉如何在Java中終止一個線程

    工作中我們經(jīng)常會用到線程,一般情況下我們讓線程執(zhí)行就完事了,那么你們有沒有想過如何去終止一個正在運(yùn)行的線程呢?本文就來帶大家一起看看
    2023-03-03

最新評論