色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

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

3天內不再提示

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

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

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

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

實現序列化和反序列化為什么要實現Serializable接口?

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

我要為serialVersionUID指定個什么值?

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

序列化和反序列化

序列化:把對象轉換為字節序列的過程稱為對象的序列化。

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

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

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

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

下面先給出結論:

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

理由:

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

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

/**Cachethehashcodeforthestring*/
privateinthash;//Defaultto0

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

......
}

String類型實現了Serializable接口,并顯示指定serialVersionUID的值。

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


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

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

實現序列化和反序列化為什么要實現Serializable接口?

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

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

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

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

在實際開發中, 不顯示指定serialVersionUID的情況會導致什么問題? 如果我們的類寫完后不再修改, 那當然不會有問題, 但這在實際開發中是不可能的,我們的類會不斷迭代, 一旦類被修改了,那舊對象反序列化就會報錯. 所以在實際開發中, 我們都會顯示指定一個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("序列化前的結果:"+user);

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

結果

先注釋掉反序列化代碼,執行序列化代碼,然后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+'''+
'}';
}
}

再注釋掉序列化代碼執行反序列化代碼,最后結果如下:

序列化前的結果: 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報錯結果為序列化與反序列化產生的serialVersionUID不一致。

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

privatestaticfinallongserialVersionUID=1L;

再執行上述步驟, 測試結果如下:

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

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

Java序列化的其他特性

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

我們來測試下這個結論:

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("序列化前的結果:"+user);
serialize(user);
UserdUser=deserialize();
System.out.println("反序列化后的結果:"+dUser);
}
}

結果

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

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

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

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

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

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

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

審核編輯:彭靜

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

    關注

    33

    文章

    8691

    瀏覽量

    151703
  • 網絡傳輸
    +關注

    關注

    0

    文章

    139

    瀏覽量

    17434
  • static
    +關注

    關注

    0

    文章

    33

    瀏覽量

    10397

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

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

收藏 人收藏

    評論

    相關推薦

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

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

    序列化哈希表到文件

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

    Java序列化的機制和原理

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

    c語言序列化和反序列化有何區別

    這里寫自定義目錄標題c語言序列化和反序列化tplut.htplut.c測試代碼參考c語言序列化和反序列化網絡調用,數據傳輸都需要把數據序列化
    發表于 07-14 07:32

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

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

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

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

    理解PHP反序列化漏洞

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

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

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

    C#實現對象序列化的三種方式是什么

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

    python序列化對象

    序列化對象:將對象轉換為可以存儲或傳輸的形式。 (1) 用于存儲:將對象的字節序列存儲到文件中,程序退出后不會消失,便于后續使用。
    的頭像 發表于 03-10 09:57 ?2363次閱讀

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

    什么是序列化? “序列化”(Serialization )的意思是將一個對象轉化為字節流。 這里說的對象可以理解為“面向對象”里的那個對象,具體的就是存儲在內存中的對象數據。 與之相反的過程是“反序列化
    的頭像 發表于 09-14 17:22 ?2654次閱讀
    什么是<b class='flag-5'>序列化</b> 為什么要<b class='flag-5'>序列化</b>

    ROS中的序列化實現

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

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

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

    Java序列化怎么使用

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

    什么時候需要Boost序列化

    程序開發中,序列化是經常需要用到的。像一些相對高級語言,比如JAVA, C#都已經很好的支持了序列化,那么C++呢?當然一個比較好的選擇就是用Boost,這個號稱C++準標準庫的東西。 什么時候需要
    的頭像 發表于 11-10 10:14 ?448次閱讀
    主站蜘蛛池模板: 伊人久久大香线蕉综合影 | 日本肉肉口番工全彩动漫 | 久久久免费热线精品频 | 国产色精品久久人妻无码看片 | 青柠在线观看视频在线高清 | 白丝女仆被强扒内裤 | 久久九九精品国产自在现线拍 | 小雪奶水涨翁工帮吸的推荐语录 | 国产精品99久久久久久AV | 喜马拉雅听书免费版 | 久久资源365| 无码爽死成人777在线观看网站 | 浪潮AV色综合久久天堂 | 2020久久精品永久免费 | 菠萝菠萝蜜免费播放高清 | 捏奶动态图吃奶动态图q | 免费光看午夜请高视频 | 亚洲AV美女成人网站P站 | 国产伦精品一区二区三区精品 | 99久久re6热精品首页 | 97人摸人人澡人人人超一碰 | 久久国产加勒比精品无码 | 欧美乱妇狂野欧美在线视频 | 最近中文字幕完整版高清 | 无码专区无码专区视频网网址 | 理论片午午伦夜理片2021 | 麻豆精品传媒2021网站入口 | 亚洲AV无码偷拍在线观看 | 黄色三级三级三级免费看 | 亚洲熟伦熟女专区 | 久久中文字幕免费视频 | 99在线观看免费视频 | 日韩精品免费一区二区 | 亚洲AV久久婷婷蜜臀无码不卡 | 早乙女由依在线观看 | 亚洲中字慕日产2020 | 国产精品伦一区二区三级视频 | 无限资源在线完整高清观看1 | 国产高清视频在线播放www色 | 亚洲福利精品电影在线观看 | 亚洲 欧美 日本 国产 高清 |