對java序列化和反序列化的理解和測試
首先需要說明的是,目前的傳輸和儲存多以json為主,連xml應用看上去都不那麼廣泛了。
於是,我們需要對自己寫的類進行序列化的操作機會變少了。
但,若我們對序列化有了瞭解,總是對於理解一些問題有幫助的。(其中序列化三個字可以換成任何技術)
今天要說的就是下面這個東西
static final long serialVersionUID = -3387516993124229948L;
序列化的概念
序列化:把物件轉化為位元組序列的過程。
反過來說就是反序列化。
序列化的應用
1、儲存物件,可以是永久的儲存在硬碟的一個檔案上,也可以是儲存在redis支援序列化儲存的容器中。 2、網路上遠端傳輸物件。 提到serialVersionUID,可能有些人很久自己寫過了。其實你還是經常用的。即使你用json進行序列化遠端傳輸,依舊要用到serialVersionUID。
即使是String也是一樣。
下面用程式碼說明一下序列化的過程
不用太多語言描述,語言描述反而看不懂,我自己是這麼認為。上程式碼,不喜歡看程式碼的,請看註釋。
序列化和反序列化的測試類
package test; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class SVTest { public static void main(String[] args) throws Exception { // 序列化User物件 SerializeUser(); // 反序列User物件 User user = DeserializeUser(); System.out.println(user); } /** * 序列化User物件 */ private static void SerializeUser() throws FileNotFoundException, IOException { // 建立一個小明 User user = new User(1,"小明"); // ObjectOutputStream 物件輸出流 ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream( new File("D:/User.txt"))); // 序列化輸出User物件 oo.writeObject(user); System.out.println("序列化成功!"); oo.close(); } /** * 反序列User物件 */ private static User DeserializeUser() throws Exception, IOException { // ObjectInputStream 物件讀取流 ObjectInputStream ois = new ObjectInputStream(new FileInputStream( new File("D:/User.txt"))); // 反序列化User物件 User user = (User) ois.readObject(); System.out.println("反序列化成功!"); ois.close(); return user; } }
被序列化的User類
package test; public class User { // ID private int id; // 姓名 private String name; User(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
執行main方法,控制檯報錯
這個錯誤,不做多解釋了,英文很好理解。 原因大家也都很清楚,User類沒有實現序列化介面。 接下來為User類新增序列化介面的實現
package test;
import java.io.Serializable;
public class User implements Serializable {
// ID
private int id;
// 姓名
private String name;
User(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
發現有警告
先忽略執行一遍看看結果。
成功了,趕緊慶祝一下。
為什麼有警告?說一說serialVersionUID
警告在提示,沒有serialVersionUID
自動生成:如果沒有會根據類名、屬性、方法等自動生成一個serialVersionUID,所以才是警告而非錯誤。
輔助新增:有兩種方式
第一種方式生成的是1L
private static final long serialVersionUID = 1L;
第二種是根據類名、屬性、方法等生成的
private static final long serialVersionUID = -6367006705587584157L;
自動生成和輔助新增的生成方式是一樣一樣的?
是的,一樣,或者不同的生成方式原理也相同。 沒有也行,有也行,那為啥還會有警告呢,乾脆不寫算了? 不對,因為輔助新增的動作並不是每次都做,也就是第一次輔助添加了,以後基本不會變了,即使本類有所改變。 而自動生成,則每次都會改變。 每次都改變又會如何呢? 還是用程式碼說明,程式碼對於程式設計師來說是最通俗易懂的。 將我們新增的serialVersionUID刪除,看看會出現什麼結果。 先執行一遍main方法,生成一個User.txt。 成功了!並沒有什麼影響啊。 繼續 為User類性增加一個屬性:年齡
package test;
import java.io.Serializable;
public class User implements Serializable {
// ID
private int id;
// 姓名
private String name;
// 新增加的年齡屬性
private String age;
User(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
此時,註釋掉main方法中的序列化方法,只執行反序列化方法。會如何呢? 報錯了,拒絕載入。 Exception in thread "main" java.io.InvalidClassException: test.User;
local class incompatible:
stream classdesc serialVersionUID = -6367006705587584157,
local class serialVersionUID = 5139856059457605582
原因就是兩次生成的serialVersionUID 不同。 結論: 環境的變化會導致生成serialVersionUID的變化,例如不同的編譯器生成的serialVersionUID有可能不同 被序列化類本身的變化,會導致serialVersionUID發生變化 這可能不是我們想看到的。 serialVersionUID應該是唯一的,確定的,獨立的。
應該顯示的定義serialVersionUID,並賦予明確的、唯一確定的值。 作用: 在某些場合,希望類的不同版本對序列化相容,因此需要確保類的不同版本具有相同的serialVersionUID。
在某些場合,不希望類的不同版本對序列化相容,因此需要確保類的不同版本具有不同的serialVersionUID。
相關推薦
java對象的序列化和反序列化
底層 修飾 我們 puts nbsp tostring read one asics 一,對象的序列化,反序列化1.對象的序列化,就是將Object轉換成byte序列,反之叫對象的反序列化2.做序列化需要有流類,序列化流(ObjectOutputStream),是(字節的)
記一次使用Jackson對Java物件序列化和反序列化的踩坑經歷
背景大概是這樣,專案中的兩個服務A和B依賴了同一個common包的Java類,A對該類json序列化,而B對其反序列化。在一次common包升級過程中,這個Java類中增加了一個屬性,由於B其實用不到這個屬性,就只把A給升級打包了,這就導致B在反序列化時出現了一個異常:com.fasterxml.j
Java對物件的序列化和反序列化
Java提供了將物件以位元組的形式寫入到磁碟中,在需要的時候在從磁碟中恢復的功能,在網路傳輸中非常
對java序列化和反序列化的理解和測試
首先需要說明的是,目前的傳輸和儲存多以json為主,連xml應用看上去都不那麼廣泛了。 於是,我們需要對自己寫的類進行序列化的操作機會變少了。 但,若我們對序列化有了瞭解,總是對於理解一些問題有幫助的。(其中序列化三個字可以換成任何技術) 今天要說的就是下面這個東西 s
Java核心類庫-IO-對象流(實現序列化與反序列化)
.get throws 反序 code row cts new java cep 使用對象流來完成序列化和反序列化操作: ObjectOutputStream:通過writeObject()方法做序列化操作的 ObjectInputStream:通過readObje
java中什麽是序列化和反序列化
zab question .com 程序 還原 破壞 ans 但我 實現 序列化:能夠把一個對象用二進制的表示出來。 類似我第一個字節表示什麽屬性名詞,第二個字節表示什麽屬性值,第幾個字段表示有幾個屬性等。 而且這個二進制可以寫到硬
json對象的序列化和反序列化
name .cn .net序列化 object cnblogs json log con com //Json.NET序列化 string jsonData = JsonConvert.SerializeObject(對象model);
python基礎之繼承組合應用、對象序列化和反序列化,選課系統綜合示例
sel 初始 否則 通用 __init__ period 類型 反序列化 信息 繼承+組合應用示例 1 class Date: #定義時間類,包含姓名、年、月、日,用於返回生日 2 def __init__(self,name,year,mon,day):
對象序列化和反序列化的基本操作
bsp 序列 log png .cn ima images mage alt 對象序列化和反序列化的基本操作
java中的序列化和反序列化學習筆記
文件 track 反序列化 out val nts 鼠標 main version 須要序列化的Person類: package cn.itcast_07; import java.io.Serializable; /* * NotSerializableE
Java將對象寫入文件讀出——序列化與反序列化
ansi print 成員 trace 對象的引用 ack lose 靜態 spa Java類中對象的序列化工作是通過ObjectOutputStream和ObjectInputStream來完成的。 寫入: 1 File aFile=new File(
01. Java對象的序列化與反序列化簡介
語音 log -c object height 通訊 圖片 二進制 進程 Java對象的序列化與反序列化 ; 給大家講解一下什麽是序列化 & 反序列化 當兩個進程進行遠程通訊的時候,彼此相互可以發送各種類型的數據,如文本,圖片,語音和視頻等無論是任何
Serializable 指示一個類可以序列化;ICloneable支持克隆,即用與現有實例相同的值創建類的新實例(接口);ISerializable允許對象控制其自己的序列化和反序列化過程(接口)
att 文本 所有 可能 成員 強制 void inter 適用於 Serializable : 序列化是指將對象實例的狀態存儲到存儲媒體的過程。在此過程中,先將對象的公共字段和私有字段以及類的名稱(包括類所在的程序集)轉換為字節流,然後再把字節流寫入數據流。在隨後對對象進
Java基礎-IO流對象之序列化與反序列化
span 作者 創作 style -s 反序列化 ont 對象 io流 Java基礎-IO流對象之序列化與反序列化 作者:尹正傑 版權聲明:原創作品,謝絕轉載!否則將追究
java基礎序--列化和反序列化
color tran public png gin jdk style 硬盤 brush 一、什麽是序列化和反序列化: 序列化:是指把java堆內存中的對象轉換成字節(二進制流)的過程。也就是通過某種方式將java對象存儲在磁盤內存中,這個過程稱為序列化 反序列化:
2018-07-25期 Java序列化和反序列化編程小案例
測試 product set pri get sof serial span not package cn.sjq.Serializable.java;import java.io.FileInputStream;import java.io.FileOutputStrea
Java 之 Serializable 序列化和反序列化的概念,作用的通俗易懂的解釋
計算 transient 全部 序列化對象 語義 meta person int 較高的 遇到這個 Java Serializable 序列化這個接口,我們可能會有如下的問題a,什麽叫序列化和反序列化b,作用。為啥要實現這個 Serializable 接口,也就是為啥要序列
Java-裝飾流-物件流 - 序列化和反序列化
ObjectInputStream(反序列化) & ObjectOutputStream(序列化) 1.先寫出後讀取 2.讀取的順序必須保持一致 3.不是所有的物件都能序列化,要加上serializable接口才行 當不想對物件中的某個屬性序列化時,在屬性中新增transie
java序列化和反序列化物件
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; impo
Java 之 Serializable 序列化和反序列化的概念 通俗易懂!!!
轉自: https://blog.csdn.net/qq_27093465/article/details/78544505 遇到這個 Java Serializable 序列化這個介面,我們可能會有如下的問題a,什麼叫序列化和反序列化 b,作用。為啥要實現這個 Serializable