對Java Serializable(序列化)的理解和總結(一)

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

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

1、什麼是序列化

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.
java

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


2、爲何須要序列化

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數據庫中啊,爲何必定要序列化才能存儲呢????github

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


3、到底何時必定要序列化

結合到第二點的問題,就是說在我存儲的時候,不經過序列化也同樣完美存儲,爲何要畫蛇添足?額,通過我閱讀文檔和書籍,以及作項目的經驗總結(反正就是以前混跡在編碼中的一系列經驗總結),在存儲時須要序列化,這是確定的。你們知道的是序列化是將對象進行流化存儲,咱們有時候感受本身在項目中並無進行序列化操做,也同樣是存進去了,那麼對象須要通過序列化才能存儲的說法,彷佛從這兒就給閹割了。事實到底是怎樣的呢?sql

首先看咱們經常使用的數據類型類聲明:數據庫

   
   
   
   
public final class String implements java.io.Serializable, Comparable<String>, CharSequence

   
   
   
   
public class Date implements java.io.Serializable, Cloneable, Comparable
而像其餘int、long、boolean類型等,都是基本數據類型,數據庫裏面有與之對應的數據結構。從上面的類聲明來看,咱們覺得的沒有進行序列化,實際上是在聲明的各個不一樣變量的時候,由具體的數據類型幫助咱們實現了序列化操做。

拿到這兒的時候,就又有一個問題,既然實體類的變量都已經幫助咱們實現了序列化,爲何咱們仍然要顯示的讓類實現serializable接口呢?數據結構

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

若是有注意觀察的話,發現序列化操做用於存儲時,通常是對於NoSql數據庫,而在使用Nosql數據庫進行存儲時,用「freeze」這個說法來理解是再恰當不過了,請在NoSql數據庫中,給我找出個varchar,int之類的數據結構出來? 若是沒有,但咱們又確實須要進行存儲,那麼,此時程序員再不將對象進行序列化,更待什麼時候?

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

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

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


3、是否必定要實現Serializable接口序列化

上回說到了關於序列化的一些基本狀況,那麼,接下來的一個問題是:若是咱們要實現序列化操做,是否必定要經過實現Serializable接口的方式?PS:其實,我只是不明白,爲何你們一提到序列化就說特別簡單,實現Serializable接口就OK了?我就一直在想,這是不是目前咱們所能擁有的最佳選擇?

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

文章說得很清楚,圖文並茂的,那麼多選擇,本身看着辦吧。不過我最近作的一個項目使用的是protostuff!


4、使用其餘序列化實現的優缺點

誠如你們在第三節分享的連接文章所見,經過實現Serializable接口的方式去進行序列化操做,在性能上來說並非最佳選擇。那麼,在性能考慮的狀況下,不少人都會選擇其餘更爲高效率的產品替代serializable接口,如今問題來了:

1,若是我經過Serializable接口實現,那麼我只須要在類聲明時實現它便可

2,若是我經過其餘方式實現,那麼我將不得不本身重寫工具類,不能再經過實現serializable接口的方式去進行序列化了。在使用上,大大的不怎麼方便!

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

跪求指點!!!!!


5、總結

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

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

相關文章
相關標籤/搜索