1. 程式人生 > >談談序列化—實體bean一定要實現Serializable接口?

談談序列化—實體bean一定要實現Serializable接口?

computer 封裝 oracle數據 快捷 imp 需要 str 重聲明 eat

導讀:最近在做項目的過程中,發現一個問題,就是我們最開始的時候,傳遞參數包括返回類型,都有map類型。但是由於map每次都要匹配key值,很麻煩。所以在之後就將參數傳遞和返回類型全都改成了實體bean,並且讓每個bean都實現了Serializable接口。然後,在這裏的時候,就有點疑惑。首先:為什麽要進行序列化;其次:每個實體bean都必須實現serializabel接口嗎?最後:我做一些項目的時候,沒有實現序列化,同樣沒什麽影響,然後現在做項目需要序列化,到底什麽時候應該進行序列化操作呢?

本篇文章,是我對於序列化這個話題的一點小小的思考,可能還不太成熟,請每一個路過的人不吝賜教,在此,先謝過了!

一、什麽是序列化

In computer science, in the context of data storage, serialization is the process of translating data structures or object state into a format that can be stored (for example, in a file or memory buffer, or transmitted across a network connection link) and reconstructed later in the same or another computer environment.[1] When the resulting series of bits is reread according to the serialization format, it can be used to create a semantically identical clone of the original object.

那我也有看過很多的博客包括書,但是我之前其實一直不太理解這個序列化,雖然一直都在用。今天在看資料 的時候,發現導致這種現象的原因,可能是我之前看的一些介紹裏面,忽略了一個很關鍵的因素:object state info對象的狀態信息 。也就是說,其實序列化,它是完整的保存了某一狀態下的對象信息,是一個整體,而不是零散的!我在一個IBM工程師的博客裏面看到一個說法,我感覺對於我理解序列化很有幫助,他說序列化的過程,就是一個“freeze”的過程,它將一個對象freeze住,然後進行存儲,等到再次需要的時候,再將這個對象de-freeze就可以立即使用。


二、為什麽需要序列化

1,存儲對象在存儲介質中,以便在下次使用的時候,可以很快捷的重建一個副本。也就是When the resulting series of bits is reread according to the serialization format, it can be used to create a semantically identical clone of the original object.

問題:我沒有實現序列化的時候,我一樣可以存入到我的sqlserver或者MySQL、Oracle數據庫中啊,為什麽一定要序列化才能存儲呢????

2,便於數據傳輸,尤其是在遠程調用的時候!


三、到底什麽時候一定要序列化

結合到第二點的問題,就是說在我存儲的時候,不通過序列化也一樣完美存儲,為什麽要多此一舉?額,經過我閱讀文檔和書籍,以及做項目的經驗總結(反正就是之前混跡在編碼中的一系列經驗總結),在存儲時需要序列化,這是肯定的。大家知道的是序列化是將對象進行流化存儲,我們有時候感覺自己在項目中並沒有進行序列化操作,也一樣是存進去了,那麽對象需要經過序列化才能存儲的說法,似乎從這兒就給閹割了。事實究竟是怎樣的呢?

首先看我們常用的數據類型類聲明:

[java] view plain copy
  1. <span style="font-family:KaiTi_GB2312;font-size:18px;">public final class String implements java.io.Serializable, Comparable<String>, CharSequence</span>

[java] view plain copy
  1. <span style="font-family:KaiTi_GB2312;font-size:18px;">public class Date implements java.io.Serializable, Cloneable, Comparable</span>

而像其他int、long、boolean類型等,都是基本數據類型,數據庫裏面有與之對應的數據結構。從上面的類聲明來看,我們以為的沒有進行序列化,其實是在聲明的各個不同變量的時候,由具體的數據類型幫助我們實現了序列化操作。

拿到這兒的時候,就又有一個問題,既然實體類的變量都已經幫助我們實現了序列化,為什麽我們仍然要顯示的讓類實現serializable接口呢?

請註意我以上的說法:首先,序列化的目的有兩個,第一個是便於存儲,第二個是便於傳輸。我們一般的實體類不需要程序員再次實現序列化的時候,請想兩個問題:第一:存儲媒體裏面,是否是有其相對應的數據結構?第二:這個實體類,是否需要遠程傳輸(或者兩個不同系統甚至是分布式模塊之間的調用)?

如果有註意觀察的話,發現序列化操作用於存儲時,一般是對於NoSql數據庫,而在使用Nosql數據庫進行存儲時,用“freeze”這個說法來理解是再恰當不過了,請在NoSql數據庫中,給我找出個varchar,int之類的數據結構出來? 如果沒有,但我們又確實需要進行存儲,那麽,此時程序員再不將對象進行序列化,更待何時?

備註:如果有人打開過Serializable接口的源碼,就會發現,這個接口其實是個空接口,那麽這個序列化操作,到底是由誰去實現了呢?其實,看一下接口的註釋說明就知道,當我們讓實體類實現Serializable接口時,其實是在告訴JVM此類可被序列化,可被默認的序列化機制序列化。

然後,需要說明的是,當我們在實體類聲明實現Serializable接口時,再次進行觀察,會發現這些類是需要被遠程調用的。也就是說需要或者可能需要被遠程調用,這就是序列化便於傳輸的用途。

慎重聲明:以上所有言論,都是本寶寶經過項目中的具體觀察,以及閱讀一些文章之後的所謂經驗之談,且看且見諒吧!


三、是否一定要實現Serializable接口序列化

上回說到了關於序列化的一些基本情況,那麽,接下來的一個問題是:如果我們要實現序列化操作,是否一定要通過實現Serializable接口的方式?PS:其實,我只是不明白,為什麽大家一提到序列化就說特別簡單,實現Serializable接口就OK了?我就一直在想,這是否是目前我們所能擁有的最佳選擇?

請大家先看一篇文章分析:https://github.com/eishay/jvm-serializers/wiki

文章說得很清楚,圖文並茂的,那麽多選擇,自己看著辦吧。不過我最近做的一個項目使用的是protostuff!


四、使用其他序列化實現的優缺點

誠如大家在第三節分享的鏈接文章所見,通過實現Serializable接口的方式去進行序列化操作,在性能上來講並不是最佳選擇。那麽,在性能考慮的情況下,很多人都會選擇其他更為高效率的產品替代serializable接口,現在問題來了:

1,如果我通過Serializable接口實現,那麽我只需要在類聲明時實現它即可

2,如果我通過其他方式實現,那麽我將不得不自己重寫工具類,不能再通過實現serializable接口的方式去進行序列化了。在使用上,大大的不怎麽方便!

PS:項目中總會用到個什麽redis,mongoDB啥的,其實每次存取都有那麽一個數據封裝處理的過程,額,也差不了這一點了。那麽有沒有現成的人家封裝好的呢?自己找吧,肯定是有的。其實,我就是不明白,如果是用了第三方的工具去實現序列化,那麽在序列化進行遠程調用的時候,到底應該在哪兒進行顯示的序列化或者反序列操作?我剛開始想在Dao層,但這樣子的話,自己模塊操作不也得來那麽一波序列化反序列化操作嘛。因為我目前確實只是在從NoSql數據庫中存取數據時用到了第三方的序列化工具,而在遠程調用的時候,沒有啊!以前都是直接實現Serializable接口的,唉。。。。學藝不精啊!

跪求指點!!!!!


五、總結

其實,很長的一段時間裏,我一直以為java底層包自帶的方法一定會是最好的,包括各個框架,我都更願意去用它本身就有的工具。但是,可能那些自帶的方法,尤其是向Serializable接口,從jdk1.1開始就有了,經過了長時間的考驗,性能上可能不是最好的,但它的穩定性絕對是值得肯定的。那麽,其實在使用的時候,還是根據自身的情況考慮吧。在技術乃至於架構或者說各種系統設計,最實用最適合的,才是最好了!

其實我還有一個問題,不見得自己模塊會和數據庫部署到同一個機器上啊,所以還是得考慮都傳輸時的序列化問題,那如果使用第三方的工具,不都得來那麽一波嘛,這代碼量就又活生生的多了那麽點兒。唉,不說了,我這是越說越暈,回家吃飯!

談談序列化—實體bean一定要實現Serializable接口?