最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java教程之對象序列化使用基礎示例詳解

 更新時間:2014年01月28日 15:06:02   作者:  
所謂對象序列化就是將對象的狀態(tài)轉換成字節(jié)流,以后可以通過這些值再生成相同狀態(tài)的對象,下面詳細介紹一下java對象的序列化使用方法

這個過程也可以通過網(wǎng)絡實現(xiàn),可以先在Windows機器上創(chuàng)建一個對象,對其序列化,然后通過網(wǎng)絡發(fā)給一臺Unix機器,然后在那里準確無誤地重新"裝配"。像RMI、Socket、JMS、EJB它們中的一種,彼此為什么能夠傳遞Java對象,當然都是對象序列化機制的功勞。 

Java對象序列化機制一般來講有兩種用途:

Java的JavaBeans: Bean的狀態(tài)信息通常是在設計時配置的,Bean的狀態(tài)信息必須被存起來,以便當程序運行時能恢復這些狀態(tài)信息,這需要將對象的狀態(tài)保存到文件中,而后能夠通過讀入對象狀態(tài)來重新構造對象,恢復程序狀態(tài)。
RMI允許象在本機上一樣操作遠程機器上的對象;或使用套接字在網(wǎng)絡上傳送對象的程序來說,這些都是需要實現(xiàn)serializaiton機制的。
我們通過讓類實現(xiàn)Java.io.Serializable 接口可以將類序列化。這個接口是一個制造者(marker)接口。也就是說,對于要實現(xiàn)它的類來說,該接口不需要實現(xiàn)任何方法。它主要用來通知Java虛擬機(JVM),需要將一個對象序列化。

對于這個,有幾點我們需要明確:

并非所有類都可以序列化,在cmd下,我們輸入serialver Java.net.Socket,可以得到socket是否可序列化的信息,實際上socket是不可序列化的。
Java有很多基礎類已經(jīng)實現(xiàn)了serializable接口,比如string,vector等。但是比如hashtable就沒有實現(xiàn)serializable接口。
將對象讀出或者寫入流的主要類有兩個: ObjectOutputStream與ObjectInputStream .ObjectOutputStream 提供用來將對象寫入輸出流的writeObject方法, ObjectInputStream提供從輸入流中讀出對象的readObject方法。使用這些方法的對象必須已經(jīng)被序列化的。也就是說,必須已經(jīng)實現(xiàn) Serializable接口。如果你想writeobject一個hashtable對象,那么,會得到一個異常。
序列化的過程就是對象寫入字節(jié)流和從字節(jié)流中讀取對象。將對象狀態(tài)轉換成字節(jié)流之后,可以用Java.io包中的各種字節(jié)流類將其保存到文件中,管道到另一線程中或通過網(wǎng)絡連接將對象數(shù)據(jù)發(fā)送到另一主機。對象序列化功能非常簡單、強大,在RMI、Socket、JMS、EJB都有應用。對象序列化問題在網(wǎng)絡編程中并不是最激動人心的課題,但卻相當重要,具有許多實用意義。
對象序列化可以實現(xiàn)分布式對象。主要應用例如:RMI要利用對象序列化運行遠程主機上的服務,就像在本地機上運行對象時一樣。
Java對象序列化不僅保留一個對象的數(shù)據(jù),而且遞歸保存對象引用的每個對象的數(shù)據(jù)??梢詫⒄麄€對象層次寫入字節(jié)流中,可以保存在文件中或在網(wǎng)絡連接上傳遞。利用對象序列化可以進行對象的“深復制”,即復制對象本身及引用的對象本身。序列化一個對象可能得到整個對象序列。
Java序列化比較簡單,通常不需要編寫保存和恢復對象狀態(tài)的定制代碼。實現(xiàn)Java.io.Serializable接口的類對象可以轉換成字節(jié)流或從字節(jié)流恢復,不需要在類中增加任何代碼。只有極少數(shù)情況下才需要定制代碼保存或恢復對象狀態(tài)。這里要注意:不是每個類都可序列化,有些類是不能序列化的,例如涉及線程的類與特定JVM有非常復雜的關系。

序列化機制:

序列化分為兩大部分:序列化 和反序列化 。序列化是這個過程的第一部分,將數(shù)據(jù)分解成字節(jié)流,以便存儲在文件中或在網(wǎng)絡上傳輸。反序列化就是打開字節(jié)流并重構對象。對象序列化不僅要將基本數(shù)據(jù)類型轉換成字節(jié)表示,有時還要恢復數(shù)據(jù)。恢復數(shù)據(jù)要求有恢復數(shù)據(jù)的對象實例。ObjectOutputStream中的序列化過程與字節(jié)流連接,包括對象類型和版本信息。反序列化時,JVM用頭信息生成對象實例,然后將對象字節(jié)流中的數(shù)據(jù)復制到對象數(shù)據(jù)成員中。下面我們分兩大部分來闡述:

處理對象流:(序列化過程和反序列化過程)
Java.io包有兩個序列化對象的類。ObjectOutputStream負責將對象寫入字節(jié)流,ObjectInputStream從字節(jié)流重構對象。
我們先了解ObjectOutputStream類吧。ObjectOutputStream類擴展DataOutput接口。
writeObject() 方法是最重要的方法,用于對象序列化。如果對象包含其他對象的引用,則writeObject()方法遞歸序列化這些對象。每個 ObjectOutputStream維護序列化的對象引用表,防止發(fā)送同一對象的多個拷貝。(這點很重要)由于writeObject()可以序列化整組交叉引用的對象,因此同一ObjectOutputStream實例可能不小心被請求序列化同一對象。這時,進行反引用序列化,而不是再次寫入對象字節(jié)流。

下面,讓我們從例子中來了解ObjectOutputStream這個類吧。

復制代碼 代碼如下:

// 序列化 today's date 到一個文件中. 
FileOutputStream  f = new  FileOutputStream ("tmp" ); 
ObjectOutputStream  s = new  ObjectOutputStream (f); 
s.writeObject("Today" ); 
s.writeObject(new  Date ()); 
s.flush();


現(xiàn)在,讓我們來了解ObjectInputStream這個類。它與ObjectOutputStream相似。它擴展DataInput接口。 ObjectInputStream中的方法鏡像DataInputStream中讀取Java基本數(shù)據(jù)類型的公開方法。readObject()方法從字節(jié)流中反序列化對象。每次調(diào)用readObject()方法都返回流中下一個Object。對象字節(jié)流并不傳輸類的字節(jié)碼,而是包括類名及其簽名。 readObject()收到對象時,JVM裝入頭中指定的類。如果找不到這個類,則readObject()拋出 ClassNotFoundException,如果需要傳輸對象數(shù)據(jù)和字節(jié)碼,則可以用RMI框架。ObjectInputStream的其余方法用于定制反序列化過程。
例子如下:
復制代碼 代碼如下:

//從文件中反序列化 string 對象和 date 對象 
FileInputStream  in = new  FileInputStream ("tmp" ); 
ObjectInputStream  s = new  ObjectInputStream (in); 
String  today = (String )s.readObject(); 
Date  date = (Date )s.readObject();


定制序列化過程:
序列化通常可以自動完成,但有時可能要對這個過程進行控制。java可以將類聲明為serializable,但仍可手工控制聲明為static或transient的數(shù)據(jù)成員。
例子:一個非常簡單的序列化類。
復制代碼 代碼如下:

public  class  simpleSerializableClass implements  Serializable { 
String  sToday="Today:" ; 
transient  Date  dtToday=new  Date (); 
}


序列化時,類的所有數(shù)據(jù)成員應可序列化除了聲明為transient 或static的成員。將變量聲明為transient告訴JVM我們會負責將變元序列化。將數(shù)據(jù)成員聲明為transient后,序列化過程就無法將其加進對象字節(jié)流中,沒有從transient數(shù)據(jù)成員發(fā)送的數(shù)據(jù)。后面數(shù)據(jù)反序列化時,要重建數(shù)據(jù)成員(因為它是類定義的一部分),但不包含任何數(shù)據(jù),因為這個數(shù)據(jù)成員不向流中寫入任何數(shù)據(jù)。記住,對象流不序列化static或transient。我們的類要用writeObject()與 readObject()方法以處理這些數(shù)據(jù)成員。使用writeObject()與readObject()方法時,還要注意按寫入的順序讀取這些數(shù)據(jù)成員。
關于如何使用定制序列化的部分代碼如下
復制代碼 代碼如下:

//重寫writeObject()方法以便處理transient的成員。 
public  void  writeObject(ObjectOutputStream  outputStream) throws  IOException { 
outputStream.defaultWriteObject();//使定制的writeObject()方法可以 
//利用自動序列化中內(nèi)置的邏輯。 
outputStream.writeObject(oSocket.getInetAddress()); 
outputStream.writeInt(oSocket.getPort()); 

//重寫readObject()方法以便接收transient的成員。 
private  void  readObject(ObjectInputStream  inputStream) throws IOException , 
ClassNotFoundException { 
inputStream.defaultReadObject();//defaultReadObject()補充自動序列化 
InetAddress  oAddress=(InetAddress )inputStream.readObject(); 
int  iPort =inputStream.readInt(); 
oSocket = new  Socket (oAddress,iPort); 
iID=getID(); 
dtToday =new  Date (); 



完全定制序列化過程:
如果一個類要完全負責自己的序列化,則實現(xiàn)Externalizable接口而不是Serializable接口。Externalizable接口定義包括兩個方法writeExternal()與readExternal()。利用這些方法可以控制對象數(shù)據(jù)成員如何寫入字節(jié)流.類實現(xiàn) Externalizable時,頭寫入對象流中,然后類完全負責序列化和恢復數(shù)據(jù)成員,除了頭以外,根本沒有自動序列化。這里要注意了。聲明類實現(xiàn) Externalizable接口會有重大的安全風險。writeExternal()與readExternal()方法聲明為public,惡意類可以用這些方法讀取和寫入對象數(shù)據(jù)。如果對象包含敏感信息,則要格外小心。這包括使用安全套接或加密整個字節(jié)流。到此為至,我們學習了序列化的基礎部分知識。

相關文章

  • 解析Java?中for循環(huán)和foreach循環(huán)哪個更快

    解析Java?中for循環(huán)和foreach循環(huán)哪個更快

    這篇文章主要介紹了Java中for循環(huán)和foreach循環(huán)哪個更快示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • java中多線程加鎖的四種方式

    java中多線程加鎖的四種方式

    Java中實現(xiàn)多線程安全的關鍵是加鎖,主要方式有synchronized關鍵字、ReentrantLock類、ReadWriteLock接口和Semaphore類,本文就來介紹一下這四種方式,感興趣的可以了解一下
    2024-10-10
  • SpringBoot Redis安裝過程詳解

    SpringBoot Redis安裝過程詳解

    這篇文章主要介紹了SpringBoot Redis安裝過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-02-02
  • Java多態(tài)性抽象類與接口細致詳解

    Java多態(tài)性抽象類與接口細致詳解

    這篇文章主要給大家介紹了關于Java中方法使用的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-08-08
  • SpringCloud基于Feign實現(xiàn)遠程調(diào)用的問題小結

    SpringCloud基于Feign實現(xiàn)遠程調(diào)用的問題小結

    這篇文章主要介紹了SpringCloud基于Feign遠程調(diào)用,通過使用 Feign 的方式,我們可以更加優(yōu)雅地進行多參數(shù)的遠程調(diào)用,避免了手動拼接URL或構建復雜的請求體,需要的朋友可以參考下
    2024-02-02
  • java多次嵌套循環(huán)查詢數(shù)據(jù)庫導致代碼中數(shù)據(jù)處理慢的解決

    java多次嵌套循環(huán)查詢數(shù)據(jù)庫導致代碼中數(shù)據(jù)處理慢的解決

    這篇文章主要介紹了java多次嵌套循環(huán)查詢數(shù)據(jù)庫導致代碼中數(shù)據(jù)處理慢的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • IDEA中Mybatis的MGB使用逆向工程配置的詳細教程

    IDEA中Mybatis的MGB使用逆向工程配置的詳細教程

    這篇文章主要介紹了IDEA中Mybatis的MGB使用逆向工程配置,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • Java基于深度優(yōu)先遍歷的隨機迷宮生成算法

    Java基于深度優(yōu)先遍歷的隨機迷宮生成算法

    今天小編就為大家分享一篇關于Java基于深度優(yōu)先遍歷的隨機迷宮生成算法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • SpringBoot文件上傳與下載功能實現(xiàn)詳解

    SpringBoot文件上傳與下載功能實現(xiàn)詳解

    文件上傳與下載是Web應用開發(fā)中常用的功能之一。接下來我們將討論如何在Spring?Boot的Web應用開發(fā)中,如何實現(xiàn)文件的上傳與下載,感興趣的可以了解一下
    2022-10-10
  • Java語言之包和繼承詳解

    Java語言之包和繼承詳解

    這篇文章主要介紹了java的包和繼承,結合實例形式詳細分析了Java繼承的概念、原理、用法及相關操作注意事項,需要的朋友可以參考下
    2021-09-09

最新評論

赫章县| 中牟县| 郯城县| 囊谦县| 昭苏县| 双辽市| 辽中县| 涟源市| 樟树市| 曲沃县| 宝应县| 霞浦县| 阜平县| 邵阳市| 云梦县| 白河县| 财经| 应城市| 乐东| 赤城县| 樟树市| 开远市| 子长县| 小金县| 新乐市| 翁源县| 谷城县| 靖安县| 图木舒克市| 凌海市| 普兰店市| 茶陵县| 西昌市| 澎湖县| 准格尔旗| 伊金霍洛旗| 甘孜县| 渑池县| 娄烦县| 化州市| 永寿县|