建議14:使用序列化類的私有方法巧妙的解決部分屬性持久化問題琴锭。
對于不想持久化的屬性有幾種方法:
- 對于一些屬性不想持久話的可以用transient關(guān)鍵字,但是這也意味著該類失去了分布式部署的功能。一旦遭遇性能瓶頸,想再實(shí)現(xiàn)分布式部署就不可能了。
- 新增業(yè)務(wù)對象缰儿,也就是說把不想持久化的屬性封裝到另一個(gè)類里面。然而增加了工作量散址,并不是最優(yōu)的做法乖阵。
- 請求端過濾,就是請求的一方不需要哪個(gè)屬性就過濾掉预麸,方案可行但是不合規(guī)矩瞪浸,設(shè)計(jì)不對。
- 變更傳輸契約吏祸,例如改用xml傳輸对蒲,或者重建一個(gè)web service服務(wù),可以做,但是成本太高蹈矮。(不懂)
然后作者給出了他的解決方法:
在需要序列化的類里面重寫writeObject(),和readObject()方法砰逻,因?yàn)樾蛄谢头葱蛄谢謩e回調(diào)這兩個(gè)方法。
//序列化委托
privare void writeObject(java.io.ObjectOutputStream out) throws IOException{
out.defaultWriteObject();
out.writeInt(salary.getBasepay());//需要序列化的屬性泛鸟,salary類省略
}
//反序列化委托
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
salary = new Salary(in.readInt(),0);//不想持久化的保密數(shù)據(jù)第二個(gè)參數(shù)傳0蝠咆;
}
Java調(diào)用ObjectOutputStream類把一個(gè)對象轉(zhuǎn)換成流數(shù)據(jù)時(shí),會(huì)通過反射檢查被序列化的類是否有writeObject方法北滥,并且檢查是否符合私有刚操、無返回值的特性,若有碑韵,則會(huì)委托該方法進(jìn)行對象序列化赡茸,若沒有缎脾,則由ObjectOutputStream按照默認(rèn)規(guī)則繼續(xù)序列化祝闻,同樣,在從流數(shù)據(jù)恢復(fù)成實(shí)例對象時(shí)遗菠,也會(huì)檢查是否有一個(gè)私有的readObject方法联喘,如有,則會(huì)通過該方法讀取屬性值辙纬。
說明:
- out.defaultWriteObject()是告知JVM按照默認(rèn)的規(guī)則寫入對象豁遭,寫在前面。
- in.defaultReadObject()告知JVM按照默認(rèn)的規(guī)則讀入對象贺拣,寫在前面蓖谢。
- out.writeXXX和in.readXXX分別是寫入和讀出相應(yīng)的值。