在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

static屬性為什么不會被序列化

Android編程精選 ? 來源:椰子Tyshawn ? 作者:椰子Tyshawn ? 2022-07-15 11:03 ? 次閱讀

做服務化,需要把所有model包里的類都實現(xiàn)Serializable接口, 同時還要顯示指定serialVersionUID的值。聽到這個需求,我腦海里就突然出現(xiàn)了好幾個問題,比如說:

序列化和反序列化是什么?

實現(xiàn)序列化和反序列化為什么要實現(xiàn)Serializable接口?

實現(xiàn)Serializable接口就算了,為什么還要顯示指定serialVersionUID的值?

我要為serialVersionUID指定個什么值?

下面我們來一一解答這幾個問題。

序列化和反序列化

序列化:把對象轉(zhuǎn)換為字節(jié)序列的過程稱為對象的序列化。

反序列化:把字節(jié)序列恢復為對象的過程稱為對象的反序列化。

什么時候需要用到序列化和反序列化呢?

當我們只在本地JVM里運行下Java實例,這個時候是不需要什么序列化和反序列化的, 但當我們需要將內(nèi)存中的對象持久化到磁盤, 數(shù)據(jù)庫中時,當我們需要與瀏覽器進行交互時, 當我們需要實現(xiàn)RPC時,這個時候就需要序列化和反序列化了。

前兩個需要用到序列化和反序列化的場景,是不是讓我們有一個很大的疑問? 我們在與瀏覽器交互時,還有將內(nèi)存中的對象持久化到數(shù)據(jù)庫中時,好像都沒有去進行序列化和反序列化,因為我們都沒有實現(xiàn)Serializable接口, 但一直正常運行。

下面先給出結(jié)論:

只要我們對內(nèi)存中的對象進行持久化或網(wǎng)絡傳輸, 這個時候都需要序列化和反序列化.

理由:

服務器與瀏覽器交互時真的沒有用到Serializable接口嗎? JSON格式實際上就是將一個對象轉(zhuǎn)化為字符串, 所以服務器與瀏覽器交互時的數(shù)據(jù)格式其實是字符串, 我們來看來String類型的源碼:

publicfinalclassString
implementsjava.io.Serializable,Comparable,CharSequence{
/**Thevalueisusedforcharacterstorage.*/
privatefinalcharvalue[];

/**Cachethehashcodeforthestring*/
privateinthash;//Defaultto0

/**useserialVersionUIDfromJDK1.0.2forinteroperability*/
privatestaticfinallongserialVersionUID=-6849794470754667710L;

......
}

String類型實現(xiàn)了Serializable接口,并顯示指定serialVersionUID的值。

然后我們再來看對象持久化到數(shù)據(jù)庫中時的情況,Mybatis數(shù)據(jù)庫映射文件里的insert代碼:


INSERTINTOt_user(name,age)VALUES(#{name},#{age})

實際上我們并不是將整個對象持久化到數(shù)據(jù)庫中, 而是將對象中的屬性持久化到數(shù)據(jù)庫中, 而這些屬性都是實現(xiàn)了Serializable接口的基本屬性。

實現(xiàn)序列化和反序列化為什么要實現(xiàn)Serializable接口?

在Java中實現(xiàn)了Serializable接口后,JVM會在底層幫我們實現(xiàn)序列化和反序列化, 如果我們不實現(xiàn)Serializable接口, 那自己去寫一套序列化和反序列化代碼也行, 至于具體怎么寫, Google一下你就知道了。

實現(xiàn)Serializable接口就算了, 為什么還要顯示指定serialVersionUID的值?

如果不顯示指定serialVersionUID,JVM在序列化時會根據(jù)屬性自動生成一個serialVersionUID, 然后與屬性一起序列化,再進行持久化或網(wǎng)絡傳輸. 在反序列化時,JVM會再根據(jù)屬性自動生成一個新版serialVersionUID,然后將這個新版serialVersionUID與序列化時生成的舊版serialVersionUID進行比較, 如果相同則反序列化成功, 否則報錯.

如果顯示指定了serialVersionUID, JVM在序列化和反序列化時仍然都會生成一個serialVersionUID, 但值為我們顯示指定的值, 這樣在反序列化時新舊版本的serialVersionUID就一致了。

在實際開發(fā)中, 不顯示指定serialVersionUID的情況會導致什么問題? 如果我們的類寫完后不再修改, 那當然不會有問題, 但這在實際開發(fā)中是不可能的,我們的類會不斷迭代, 一旦類被修改了,那舊對象反序列化就會報錯. 所以在實際開發(fā)中, 我們都會顯示指定一個serialVersionUID, 值是多少無所謂, 只要不變就行。

寫個實例測試下:

User類

不顯示指定serialVersionUID.

publicclassUserimplementsSerializable{
privateStringname;
privateIntegerage;
publicStringgetName(){
returnname;
}

publicvoidsetName(Stringname){
this.name=name;
}

publicIntegergetAge(){
returnage;
}

publicvoidsetAge(Integerage){
this.age=age;
}

@Override
publicStringtoString(){
return"User{"+
"name='"+name+'''+
",age="+age+
'}';
}
}

測試類

先進行序列化, 再進行反序列化.

publicclassSerializableTest{
privatestaticvoidserialize(Useruser)throwsException{
ObjectOutputStreamoos=newObjectOutputStream(newFileOutputStream(newFile("D:\111.txt")));
oos.writeObject(user);
oos.close();
}

privatestaticUserdeserialize()throwsException{
ObjectInputStreamois=newObjectInputStream(newFileInputStream(newFile("D:\111.txt")));
return(User)ois.readObject();
}

publicstaticvoidmain(String[]args)throwsException{
Useruser=newUser();
user.setName("tyshawn");
user.setAge(18);
System.out.println("序列化前的結(jié)果:"+user);

serialize(user);
UserdUser=deserialize();
System.out.println("反序列化后的結(jié)果:"+dUser);
}
}

結(jié)果

先注釋掉反序列化代碼,執(zhí)行序列化代碼,然后User類新增一個屬性sex。

publicclassUserimplementsSerializable{
privateStringname;
privateIntegerage;
privateStringsex;
publicStringgetName(){
returnname;
}

publicvoidsetName(Stringname){
this.name=name;
}

publicIntegergetAge(){
returnage;
}

publicvoidsetAge(Integerage){
this.age=age;
}

publicStringgetSex(){
returnsex;
}

publicvoidsetSex(Stringsex){
this.sex=sex;
}

@Override
publicStringtoString(){
return"User{"+
"name='"+name+'''+
",age="+age+
",sex='"+sex+'''+
'}';
}
}

再注釋掉序列化代碼執(zhí)行反序列化代碼,最后結(jié)果如下:

序列化前的結(jié)果: User{name='tyshawn', age=18}Exception in thread "main" java.io.InvalidClassException: org.tyshawn.SerializeAndDeserialize.User; local class incompatible: stream classdesc serialVersionUID = 1035612825366363028, local class serialVersionUID = -1830850955895931978報錯結(jié)果為序列化與反序列化產(chǎn)生的serialVersionUID不一致。

接下來我們在上面User類的基礎上顯示指定一個serialVersionUID。

privatestaticfinallongserialVersionUID=1L;

再執(zhí)行上述步驟, 測試結(jié)果如下:

序列化前的結(jié)果: User{name='tyshawn', age=18}反序列化后的結(jié)果: User{name='tyshawn', age=18, sex='null'}

顯示指定serialVersionUID后就解決了序列化與反序列化產(chǎn)生的serialVersionUID不一致的問題。

Java序列化的其他特性

先說結(jié)論, 被transient關鍵字修飾的屬性不會被序列化, static屬性也不會被序列化。

我們來測試下這個結(jié)論:

User類

publicclassUserimplementsSerializable{
privatestaticfinallongserialVersionUID=1L;
privateStringname;
privateIntegerage;
privatetransientStringsex;
privatestaticStringsignature="你眼中的世界就是你自己的樣子";
publicStringgetName(){
returnname;
}

publicvoidsetName(Stringname){
this.name=name;
}

publicIntegergetAge(){
returnage;
}

publicvoidsetAge(Integerage){
this.age=age;
}

publicStringgetSex(){
returnsex;
}

publicvoidsetSex(Stringsex){
this.sex=sex;
}

publicstaticStringgetSignature(){
returnsignature;
}

publicstaticvoidsetSignature(Stringsignature){
User.signature=signature;
}

@Override
publicStringtoString(){
return"User{"+
"name='"+name+'''+
",age="+age+
",sex='"+sex+'''+
",signature='"+signature+'''+
'}';
}
}

測試類

publicclassSerializableTest{
privatestaticvoidserialize(Useruser)throwsException{
ObjectOutputStreamoos=newObjectOutputStream(newFileOutputStream(newFile("D:\111.txt")));
oos.writeObject(user);
oos.close();
}

privatestaticUserdeserialize()throwsException{
ObjectInputStreamois=newObjectInputStream(newFileInputStream(newFile("D:\111.txt")));
return(User)ois.readObject();
}
publicstaticvoidmain(String[]args)throwsException{
Useruser=newUser();
user.setName("tyshawn");
user.setAge(18);
user.setSex("man");
System.out.println("序列化前的結(jié)果:"+user);
serialize(user);
UserdUser=deserialize();
System.out.println("反序列化后的結(jié)果:"+dUser);
}
}

結(jié)果

先注釋掉反序列化代碼, 執(zhí)行序列化代碼, 然后修改User類signature = “我的眼里只有你”, 再注釋掉序列化代碼執(zhí)行反序列化代碼, 最后結(jié)果如下:

序列化前的結(jié)果: User{name='tyshawn', age=18, sex='man', signature='你眼中的世界就是你自己的樣子'}反序列化后的結(jié)果: User{name='tyshawn', age=18, sex='null', signature='我的眼里只有你'}

static屬性為什么不會被序列化?

因為序列化是針對對象而言的,而static屬性優(yōu)先于對象存在,隨著類的加載而加載, 所以不會被序列化。

看到這個結(jié)論,是不是有人會問,serialVersionUID也被static修飾,為什么serialVersionUID會被序列化? 其實serialVersionUID屬性并沒有被序列化,JVM在序列化對象時會自動生成一個serialVersionUID,然后將我們顯示指定的serialVersionUID屬性值賦給自動生成的serialVersionUID。

原文標題:Java 序列化和反序列化,為什么要實現(xiàn) Serializable 接口?

文章出處:【微信公眾號:Android編程精選】歡迎添加關注!文章轉(zhuǎn)載請注明出處。

審核編輯:彭靜

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 接口
    +關注

    關注

    33

    文章

    8885

    瀏覽量

    152963
  • 網(wǎng)絡傳輸

    關注

    0

    文章

    143

    瀏覽量

    17826
  • static
    +關注

    關注

    0

    文章

    34

    瀏覽量

    10565

原文標題:Java 序列化和反序列化,為什么要實現(xiàn) Serializable 接口?

文章出處:【微信號:AndroidPush,微信公眾號:Android編程精選】歡迎添加關注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關推薦

    如何使用Serde進行序列化和反序列化

    Serde 是一個用于序列化和反序列化 Rust 數(shù)據(jù)結(jié)構(gòu)的庫。它支持 JSON、BSON、YAML 等多種格式,并且可以自定義序列化和反序列化方式。Serde 的特點是代碼簡潔、易于
    的頭像 發(fā)表于 09-30 17:09 ?1564次閱讀

    序列化哈希表到文件

    BinarySerialize {//把哈希表對象序列化到文件public static void Serialize(String strFile, Hashtable ht){using
    發(fā)表于 06-18 18:28

    Java序列化的機制和原理

    本文講解了Java序列化的機制和原理。從文中你可以了解如何序列化一個對象,什么時候需要序列化以及Java序列化的算法。AD:WOT2014課程推薦:實戰(zhàn)MSA:用開源軟件搭建微服務系統(tǒng)
    發(fā)表于 07-10 07:27

    c語言序列化和反序列化有何區(qū)別

    這里寫自定義目錄標題c語言序列化和反序列化tplut.htplut.c測試代碼參考c語言序列化和反序列化網(wǎng)絡調(diào)用,數(shù)據(jù)傳輸都需要把數(shù)據(jù)序列化
    發(fā)表于 07-14 07:32

    關于c語言序列化和反序列化的知識點看完你就懂了

    關于c語言序列和反序列化的知識點你就懂了
    發(fā)表于 10-15 08:47

    SpringMVC JSON框架的自定義序列化與反序列化

    ,那么jackson的@JsonSerialize就不會有觸發(fā)入口了,我們來看看fastjson的處理方式。自定義序列化相應的,使用fastjson會有相應的配置類,示例如下:/** * 統(tǒng)一輸出
    發(fā)表于 10-10 16:02

    理解PHP反序列化漏洞

    理解PHP反序列化漏洞
    發(fā)表于 09-07 11:03 ?7次下載
    理解PHP反<b class='flag-5'>序列化</b>漏洞

    java序列化和反序列化范例和JDK類庫中的序列化API

    一、序列化和反序列化的概念 把對象轉(zhuǎn)換為字節(jié)序列的過程稱為對象的序列化。 把字節(jié)序列恢復為對象的過程稱為對象的反
    發(fā)表于 09-27 10:13 ?6次下載

    C#實現(xiàn)對象序列化的三種方式是什么

    很多小伙伴一提到序列化,都會想到二進制序列化,但其實序列化并不僅僅只是二進制序列化,我們常說的對象序列化有三種方式,分別是二進制
    的頭像 發(fā)表于 02-22 16:11 ?1368次閱讀
    C#實現(xiàn)對象<b class='flag-5'>序列化</b>的三種方式是什么

    python序列化對象

    序列化對象:將對象轉(zhuǎn)換為可以存儲或傳輸?shù)男问健? (1) 用于存儲:將對象的字節(jié)序列存儲到文件中,程序退出后不會消失,便于后續(xù)使用。
    的頭像 發(fā)表于 03-10 09:57 ?2444次閱讀

    什么是序列化 為什么要序列化

    什么是序列化? “序列化”(Serialization )的意思是將一個對象轉(zhuǎn)化為字節(jié)流。 這里說的對象可以理解為“面向?qū)ο蟆崩锏哪莻€對象,具體的就是存儲在內(nèi)存中的對象數(shù)據(jù)。 與之相反的過程是“反序列化
    的頭像 發(fā)表于 09-14 17:22 ?3043次閱讀
    什么是<b class='flag-5'>序列化</b> 為什么要<b class='flag-5'>序列化</b>

    ROS中的序列化實現(xiàn)

    理解了序列化,再回到ROS。我們發(fā)現(xiàn),ROS沒有采用第三方的序列化工具,而是選擇自己實現(xiàn),代碼在roscpp_core項目下的roscpp_serialization中,見下圖。這個功能涉及的代碼量
    的頭像 發(fā)表于 09-14 17:26 ?1056次閱讀

    如何用C語言進行json的序列化和反序列化

    json是目前最為流行的文本數(shù)據(jù)傳輸格式,特別是在網(wǎng)絡通信上廣泛應用,隨著物聯(lián)網(wǎng)的興起,在嵌入式設備上,也需要開始使用json進行數(shù)據(jù)傳輸,那么,如何快速簡潔地用C語言進行json的序列化和反序列化
    的頭像 發(fā)表于 10-07 11:05 ?1813次閱讀

    Java序列化怎么使用

    轉(zhuǎn)換方式就叫做序列化。將文件或者網(wǎng)絡傳輸中得到的 byte[] 數(shù)組轉(zhuǎn)換為 java 對象就叫做反序列化。 怎么使用 如果一個 Java 對象要能被序列化,必須實現(xiàn)一個特殊
    的頭像 發(fā)表于 10-10 14:19 ?567次閱讀

    什么時候需要Boost序列化

    程序開發(fā)中,序列化是經(jīng)常需要用到的。像一些相對高級語言,比如JAVA, C#都已經(jīng)很好的支持了序列化,那么C++呢?當然一個比較好的選擇就是用Boost,這個號稱C++準標準庫的東西。 什么時候需要
    的頭像 發(fā)表于 11-10 10:14 ?556次閱讀
    主站蜘蛛池模板: 欧美高清一区二区三 | h在线国产 | jk黑色丝袜美腿老师啪啪 | 视频在线观看免费网站 | 亚洲一区二区三区免费看 | 日本一级大片 | 色综合天天综合网国产人 | 一级aaa毛片| a毛片基地免费全部香蕉 | 国模私拍一区二区三区 | 久久亚洲国产午夜精品理论片 | 女人被男人免费播放网站 | 免费国产成人午夜私人影视 | 色噜噜狠狠狠狠色综合久一 | 狠狠色噜噜狠狠狠狠97 | 国产黄色片一级 | 亚洲五月六月丁香激情 | 狠狠色噜噜| 欧美性猛交xxxx乱大交中文 | 999毛片 | 天天干夜夜谢 | 男男憋尿play按小腹 | 欧美一级特黄啪啪片免费看 | 91在线视频观看 | 手机亚洲第1页 | 国产精品伦视频观看免费 | 手机看片自拍自拍自拍 | 成人黄色免费看 | 67pao强力打造 | 九九九色 | 日韩精品在线一区二区 | 99色婷婷| 免费亚洲视频在线观看 | 久久777国产线看观看精品卜 | 特黄特色三级在线播放 | 天天摸日日添狠狠添婷婷 | jzzjlzz亚洲乱熟在线播放 | 天天干夜夜骑 | 亚洲欧洲一区二区三区在线 | 日本污视频 | 91大神大战高跟丝袜美女 |