這裏是修真院後端小課堂,每篇分享文從java
【背景介紹】【知識剖析】【常見問題】【解決方案】【編碼實戰】【擴展思考】【更多討論】【參考文獻】程序員
八個方面深度解析後端知識/技能,本篇分享的是:redis
【什麼是序列化和反序列化,在RMI中是否要實現 SERIALIZABLE 接口, SERIALVERSIONUID的用處是什麼?】數據庫
標題:後端
修真院java小課堂】什麼是序列化和反序列化,在RMI中是否要實現 SERIALIZABLE 接口, SERIALVERSIONUID的用處是什麼?網絡
開場語:數據結構
你們好,我是IT修真院西安分院第3期的學員喬名震,一枚正直純潔善良的Java程序員,今天給你們分享一下,修真院官網Java任務八,深度思考中的知識點——什麼是序列化和反序列化,在RMI中是否要實現 SERIALIZABLE 接口, SERIALVERSIONUID的用處是什麼?socket
(1)背景介紹:編碼
1.1 序列化視頻
任務六中,當咱們向Redis或Memcache中插入對象時,對象須要先序列化才能存入MemCache或redis中。
當兩個進程遠程通訊時,它們能夠向彼此發送各類類型的數據,包括文本、圖像、音頻、視頻等,這些數據經過網絡以二進制序列傳輸。當兩個Java進程通訊時,一個進程能夠將一個Java對象發送給另外一個嗎?
1)發送方須要將Java對象轉換成一個字節序列,才能在網上傳送
2)接收方須要將字節序列恢復到Java對象。
(2)知識剖析:
2.1 什麼是序列化
序列化:指把堆內存中的 Java 對象數據,經過某種方式把對象存儲到磁盤文件中或者傳遞給其餘網絡節點(在網絡上傳輸)。這個過程稱爲序列化。通俗來講就是將數據結構或對象轉換成二進制串的過程。
Java序列化是指把Java對象轉換爲字節序列的過程
2.2 什麼是反序列化?
反序列化:把磁盤文件中的對象數據或者把網絡節點上的對象數據,恢復成Java對象模型的過程。也就是將在序列化過程當中所生成的二進制串轉換成數據結構或者對象的過程
Java反序列化是指把字節序列恢復爲Java對象的過程
2.3序列化有什麼做用?
對象的序列化主要有兩種用途:
1) 把對象的字節序列永久地保存到硬盤上,一般存放在一個文件中;
2) 在網絡上傳送對象的字節序列。
對象序列化的本質是將對象的狀態經過有序字節流進行保存或傳輸,由此,靜態變量是類變量,屬於整個類,並不是專屬於每一個對象實例,所以,不序列化靜態變量。
2.4在RMI中是否要實現 Serializable 接口?
須要
首先,在跑Demo的時候,經過rmi傳輸對象時,不去實現Serializable接口,會拋異常;
其次,rmi遠程方法調用最底層是經過socket通訊來實現對象的傳輸,其數據的傳輸最後都歸結於二進制的數據包。
2.5serialVersionUID是什麼?
serialVersionUID用於序列化與反序列化過程當中的類信息校驗值。
2.6serialVersionUID的用處是什麼?
serialVersionUID適用於Java的序列化機制。簡單來講,Java的序列化機制是經過判斷類的serialVersionUID來驗證版本一致性的。在進行反序列化時,JVM會把傳來的字節流中的serialVersionUID與本地相應實體類的serialVersionUID進行比較,若是相同就認爲是一致的,能夠進行反序列化,不然就會出現序列化版本不一致的異常,便是InvalidCastException。
(3)常見問題:
java中的序列化
(4)解決方案:
java中的序列化:
須要作序列化的對象的類,必須實現序列化接口:Java.lang.Serializable 接口(這是一個標誌接口,沒有任何抽象方法),Java 中大多數類都實現了該接口,好比:String,Integer
底層會判斷,若是當前對象是 Serializable 的實例,才容許作序列化,Java對象 instanceof Serializable 來判斷。
(5)編碼實戰:
一個User類,它的對象須要序列化:
User類去實現Serializable接口:
ObjectOutputStream採用默認的序列化方式,對User類的對象的非transient的實例變量進行序列化。
ObjectInputStream採用默認的非transient的實例變量進行反序列化。
Java.IO.ObjectOutputStream:經過 writeObject()方法作序列化操做
ObjectOutputStream:表示輸出流對象
它的writeObject(Object obj)方法可對參數指定的obj對象進行序列化,把獲得的字節序列寫到一個目標輸出流中
Java.IO.ObjectInputStream:經過 readObject() 方法作反序列化操做
ObjectInputStream,表明對象輸入流,
它的readObject()方法從一個源輸入流中讀取字節,再把它們反序列化成一個對象,並將其返回。
(6)拓展思考:
6.1 transient
java語言的關鍵字,變量修飾符,若是用transient聲明一個實例變量,當對象存儲時,它的值不須要維持。換句話來講就是,用transient關鍵字標記的成員變量不參與序列化過程。
(7)參考文獻:
CSDN
百度百科
(8)更多討論:
一、serialVersionUID實際做用
假設本地數據庫中存儲了大量的user對象,後來因爲需求,要修改User類中的屬性;若是不設置SerialVersionUID,根據屬性方法等自動生成,就會出現代碼演示中的錯誤,形成的結果就是已經存儲的user對象沒法反序列化;因此設置serialVersionUID的做用是爲了向下的兼容性。
二、除了Serializable接口,還有沒有實現序列化的方式
實現Externalizable接口,它是Serializable接口的子類
被Serializable接口聲明的類的對象的內容都將被序列化,若是如今用戶但願本身指定序列化的內容,則可讓一個類實現Externalizable接口
三、rmi中實現序列化的操做在哪裏
實體類實現了Serializable接口,rmi對序列化過程進行封裝,其中ObjectOutputStream採用默認的序列化方式,對實體類的實例化對象序列化
(9)鳴謝:
(10)結束語:
今天的分享就到這裏啦,歡迎你們點贊、轉發、留言、拍磚~