javaBean为什么要实现Serializable接口?
Java的"對(duì)象序列化"能讓你將一個(gè)實(shí)現(xiàn)了Serializable接口的對(duì)象轉(zhuǎn)換成一組byte,這樣日后要用這個(gè)對(duì)象時(shí)候,你就能把這些byte數(shù)據(jù)恢復(fù)出來(lái),并據(jù)此重新構(gòu)建那個(gè)對(duì)象了。這一點(diǎn)甚至在跨網(wǎng)絡(luò)的環(huán)境下也是如此,這就意味著序列化機(jī)制能自動(dòng)補(bǔ)償操作系統(tǒng)方面的差異。也就是說(shuō),你可以在Windows機(jī)器上創(chuàng)鍵一個(gè)對(duì)象,序列化之后,再通過(guò)網(wǎng)絡(luò)傳到Unix機(jī)器上,然后在那里進(jìn)行重建。你不用擔(dān)心在不同的平臺(tái)上數(shù)據(jù)是怎樣表示的,byte順序怎樣,或者別的什么細(xì)節(jié)。
?
對(duì)象序列化本身就非常有趣,因?yàn)樗茏屇銓?shí)現(xiàn)"輕量級(jí)的persistence(lightweight persistence)"。所謂persistence是指,對(duì)象的生命周期不是由程序是否運(yùn)行決定的;在程序的兩次調(diào)用之間對(duì)象仍然還活著。通過(guò)"將做過(guò)序列化處理的對(duì)象寫(xiě)入磁盤(pán),等到程序再次運(yùn)行的時(shí)候再把它讀出來(lái)",你可以達(dá)到persistence的效果。之所以說(shuō)"輕量級(jí)",是因?yàn)槟悴荒苡孟?#34;persistent"這樣的關(guān)鍵詞來(lái)直接定義一個(gè)對(duì)象,然后讓系統(tǒng)去處理所有細(xì)節(jié)(雖然將來(lái)有可能會(huì)這樣)。相反,你必須明確地進(jìn)行序列化(serialize)和解序列化(deserialize)。如果你需要更為正式的persistence功能,可以考慮Java Data Object( 簡(jiǎn)稱(chēng)是JDO)或Hibernate之類(lèi)的工具(http://hibernate.sourceforge.net)。
?
之所以要在語(yǔ)言里加入對(duì)象序列化是因?yàn)橐盟鼇?lái)實(shí)現(xiàn)兩個(gè)重要的功能。Java的遠(yuǎn)程方法調(diào)用(Remote Method Invocation簡(jiǎn)稱(chēng)RMI)能讓你像調(diào)用自己機(jī)器上的對(duì)象那樣去調(diào)用其它機(jī)器上的對(duì)象。當(dāng)你向遠(yuǎn)程對(duì)象傳遞消息的時(shí)候,就需通過(guò)對(duì)象序列化來(lái)傳送參數(shù)和返回值了。RMI會(huì)在Thinking in Enterprise Java作討論。
我們會(huì)在第14章講到JavaBean。對(duì)JavaBean來(lái)說(shuō),對(duì)象序列化也是必不可少的。Bean的狀態(tài)信息通常是在設(shè)計(jì)時(shí)配置的。這些狀態(tài)信息必須保存起來(lái),供程序啟動(dòng)的時(shí)候用;對(duì)象序列化就負(fù)責(zé)這個(gè)工作。
序列化一個(gè)對(duì)象還是比較簡(jiǎn)單的,只要讓它實(shí)現(xiàn)Serializable接口就行了(這是一個(gè)"標(biāo)記接口(tagging interface)",沒(méi)有任何方法)。但是,當(dāng)語(yǔ)言引入序列化概念之后,它的很多標(biāo)準(zhǔn)類(lèi)庫(kù)的類(lèi),包括primitive的wrapper類(lèi),所有的容器類(lèi),以及別的很多類(lèi),都會(huì)相應(yīng)地發(fā)生改變。甚至連Class對(duì)象都會(huì)被序列化。
?
要想序列化對(duì)象,你必須先創(chuàng)建一個(gè)OutputStream,然后把它嵌進(jìn)ObjectOutputStream。這時(shí),你就能用writeObject( )方法把對(duì)象寫(xiě)入OutputStream了。讀的時(shí)候,你得把InputStream嵌到ObjectInputStream里面,然后再調(diào)用readObject( )方法。不過(guò)這樣讀出來(lái)的,只是一個(gè)Object的reference,因此在用之前,還得先下傳。
?
對(duì)象序列化最聰明的一點(diǎn)是,它不僅能保存對(duì)象的副本,而且還會(huì)跟著對(duì)象里面的reference,把它所引用的對(duì)象也保存起來(lái),然后再繼續(xù)跟蹤那些對(duì)象的reference,以此類(lèi)推。這種情形常被稱(chēng)為"單個(gè)對(duì)象所聯(lián)結(jié)的'對(duì)象網(wǎng)'"。這個(gè)機(jī)制所涵蓋的范圍不僅包括對(duì)象的成員數(shù)據(jù),而且還包含數(shù)組里面的reference。如果你要自己實(shí)現(xiàn)對(duì)象序列化的話,那么編寫(xiě)跟蹤這些鏈接的程序?qū)?huì)是一件非常痛苦的任務(wù)。但是,Java的對(duì)象序列化就能精確無(wú)誤地做到這一點(diǎn),毫無(wú)疑問(wèn),它的遍歷算法是做過(guò)優(yōu)化的。
?
---------------------------------------------------------------------
實(shí)現(xiàn)java.io.Serializable 接口的類(lèi)是可序列化的。沒(méi)有實(shí)現(xiàn)此接口的類(lèi)將不能使它們的任一狀態(tài)被序列化或逆序列化。
序列化類(lèi)的所有子類(lèi)本身都是可序列化的。這個(gè)序列化接口沒(méi)有任何方法和域,僅用于標(biāo)識(shí)序列化的語(yǔ)意。允許非序列化類(lèi)的子類(lèi)型序列化,子類(lèi)型可以假定負(fù)責(zé)保存和恢復(fù)父類(lèi)型的公有的、保護(hù)的和(如果可訪問(wèn))包的域的狀態(tài)。只要該類(lèi)(擴(kuò)展)有一個(gè)無(wú)參構(gòu)造子,可初始化它的狀態(tài),那么子類(lèi)型就可承擔(dān)上述職責(zé)。在這種情況下申明一個(gè)可序列化的類(lèi)是一個(gè)錯(cuò)誤。此錯(cuò)誤將在運(yùn)行時(shí)被檢測(cè)。就是可以把對(duì)象存到字節(jié)流,然后可以恢復(fù)!
例如:Integer實(shí)現(xiàn)了Serializable,所以可以把一個(gè)Integer的對(duì)象用IO寫(xiě)到文件里,之后再可以從文件里讀出,如你開(kāi)始寫(xiě)入的時(shí)候那個(gè)對(duì)象的intValue() 是5的話,那讀出來(lái)之后也是5。這一點(diǎn)體現(xiàn)了用序化類(lèi)的作用,即用來(lái)傳送類(lèi)的對(duì)象。
當(dāng)一個(gè)JavaBean在構(gòu)造工具內(nèi)被用戶化,并與其它Bean建立連接之后,它的所有狀態(tài)都應(yīng)當(dāng)可被保存,下一次被load進(jìn)構(gòu)造工具內(nèi)或在運(yùn)行時(shí),就應(yīng)當(dāng)是上一次修改完的信息。為了能做到這一點(diǎn),要把Bean的某些字段的信息保存下來(lái),在定義Bean時(shí)要使它實(shí)現(xiàn)Java.io.Serializable接口。例如:
public class Button implements Java.io.Serializable {……}
實(shí)現(xiàn)了序列化接口的Bean中字段的信息將被自動(dòng)保存。若不想保存某些字(這里的Bean中字段的信息將被自動(dòng)保存是什么意思?這個(gè)自動(dòng)保存是怎么實(shí)現(xiàn)的?)
段的信息則可在這些字段前冠以transient或static關(guān)鍵字,transient和static變量的信息是不可被保存的。通常,一個(gè)Bean所有公開(kāi)出來(lái)的屬性都應(yīng)當(dāng)是被保存的,也可有選擇地保存內(nèi)部狀態(tài)。Bean開(kāi)發(fā)者在修改軟件時(shí),可以添加字段,移走對(duì)其它類(lèi)的引用,改變一個(gè)字段的private、protected或public狀態(tài),這些都不影響類(lèi)的存儲(chǔ)結(jié)構(gòu)關(guān)系。然而,當(dāng)從類(lèi)中刪除一個(gè)字段,改變一個(gè)變量在類(lèi)體系中的位置,把某個(gè)字段改成transient/static,或原來(lái)是transient/static,現(xiàn)改為別的特性時(shí),都將引起存儲(chǔ)關(guān)系的變化。
所謂的Serializable,就是java提供的通用數(shù)據(jù)保存和讀取的接口。至于從什么地方讀出來(lái)和保存到哪里去都被隱藏在函數(shù)參數(shù)的背后了。這樣子,任何類(lèi)型只要實(shí)現(xiàn)了Serializable接口,就可以被保存到文件中,或者作為數(shù)據(jù)流通過(guò)網(wǎng)絡(luò)發(fā)送到別的地方。也可以用管道來(lái)傳輸?shù)较到y(tǒng)的其他程序中。這樣子極大的簡(jiǎn)化了類(lèi)的設(shè)計(jì)。只要設(shè)計(jì)一個(gè)保存一個(gè)讀取功能就能解決上面說(shuō)得所有問(wèn)題。
轉(zhuǎn)自 http://www.cnblogs.com/hoobey/p/5426727.html
轉(zhuǎn)載于:https://www.cnblogs.com/honey01/p/7918741.html
總結(jié)
以上是生活随笔為你收集整理的javaBean为什么要实现Serializable接口?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Mysql Case when 语句
- 下一篇: 11月29号例会记录