日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

实现序列化与反序列化,一定要绕开这些坑!

發(fā)布時(shí)間:2025/3/20 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实现序列化与反序列化,一定要绕开这些坑! 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

今日推薦

這 9 個(gè) Java 開源項(xiàng)目 yyds,你知道幾個(gè)?阿里技術(shù)專家推薦的20本書,免費(fèi)送!K8S 部署 SpringBoot 項(xiàng)目(一篇夠用)妙用Java 8中的 Function接口 消滅if...else(非常新穎的寫法) Nginx 入門到實(shí)戰(zhàn),新手必懂。

文章目錄

  • 序列化與反序列化的概念

  • 子類實(shí)現(xiàn)Serializable接口,父類沒有實(shí)現(xiàn),子類可以序列化嗎?

  • 類中存在引用對象,這個(gè)類對象在什么情況下可以實(shí)現(xiàn)序列化?

  • 同一個(gè)對象多次序列化之間有屬性更新,前后的序列化有什么區(qū)別?

  • 1.序列化與反序列化的概念

    先說說序列化和反序列化的概念

    • 序列化:將對象寫入到IO流中

    • 反序列化:從IO流中恢復(fù)對象

    Serializable接口是一個(gè)標(biāo)記接口,不用實(shí)現(xiàn)任何方法,標(biāo)記當(dāng)前類對象是可以序列化的,是給JVM看的。

    序列化機(jī)制允許將這些實(shí)現(xiàn)序列化接口的對象轉(zhuǎn)化為字節(jié)序列,這些字節(jié)序列可以保證在磁盤上或者網(wǎng)絡(luò)傳輸后恢復(fù)成原來的對象。序列化就是把對象存儲在JVM以外的地方,序列化機(jī)制可以讓對象脫離程序的運(yùn)行而獨(dú)立存在。

    序列化在業(yè)務(wù)代碼也許用的不多,但是在框架層面用的是很多的。

    相關(guān)技術(shù):Session的序列化或者反序列化

    先給出序列化的例子,請記住這個(gè)People類,后面會根據(jù)這個(gè)類來改造講解。

    public?class?People?{??private?Long?id;??public?People(Long?id)?{??this.id?=?id;??}??public?Long?getId()?{??return?id;??}??public?void?setId(Long?id)?{??this.id?=?id;??}??@Override??public?String?toString()?{??return?"People{"?+??"id="?+?id?+??'}';??}?? }import?java.io.*;??//?屏蔽編譯器的警告?? @SuppressWarnings("all")?? public?class?Main?{??/**??*?<h1>序列化和反序列化?People?對象</h1>??*/??private?static?void?testSerializablePeople()?throws?Exception?{??//?序列化的步驟??//?用于存儲序列化的文件,這里的java_下劃線僅僅為了說明是java序列化對象,沒有任何其他含義??File?file?=?new?File("/tmp/people_10.java_");??if?(!file.exists())?{??//?1,先得到文件的上級目錄,并創(chuàng)建上級目錄??file.getParentFile().mkdirs();??try?{??//?2,再創(chuàng)建文件??file.createNewFile();??}?catch?(IOException?e)?{??e.printStackTrace();??}??}??People?p?=?new?People(10L);??//?創(chuàng)建一個(gè)輸出流??ObjectOutputStream?oos?=?new?ObjectOutputStream(??new?FileOutputStream(file)??);??//?輸出可序列化對象??oos.writeObject(p);??//?關(guān)閉輸出流??oos.close();??//?反序列化的步驟??//?創(chuàng)建一個(gè)輸入流??ObjectInputStream?ois?=?new?ObjectInputStream(??new?FileInputStream(file)??);??//?得到反序列化的對象,這里可以強(qiáng)轉(zhuǎn)為People類型??Object?newPerson?=?ois.readObject();??//?關(guān)閉輸入流??ois.close();??System.out.println(newPerson);??}??public?static?void?main(String[]?args)?throws?Exception?{??testSerializablePeople();??}?? }

    運(yùn)行之后,看到磁盤文件因?yàn)樾蛄谢嗔艘粋€(gè)文件

    圖片

    控制臺中因反序列化輸出的對象信息打印如下:

    圖片

    2.子類實(shí)現(xiàn)Serializable接口,父類沒有實(shí)現(xiàn),子類可以序列化嗎?

    去掉父類People的implements Serializable,讓父類不實(shí)現(xiàn)序列化接口,子類Worker實(shí)現(xiàn)序列化接口

    public?class?Worker?extends?People?implements?Serializable?{??private?String?name;??private?Integer?age;??public?Worker(Long?id,?String?name,?Integer?age)?{??super(id);??this.name?=?name;??this.age?=?age;??}??}public?static?void?main(String[]?args)?throws?Exception?{??testSerizableWorker();??}??/**??*?<h2>子類實(shí)現(xiàn)序列化,?父類不實(shí)現(xiàn)序列化</h2>??*?*/??private?static?void?testSerizableWorker()?throws?Exception?{??File?file?=?new?File("/tmp/worker_10.java_");??if?(!file.exists())?{??//?1,先得到文件的上級目錄,并創(chuàng)建上級目錄??file.getParentFile().mkdirs();??try?{??//?2,再創(chuàng)建文件??file.createNewFile();??}?catch?(IOException?e)?{??e.printStackTrace();??}??}??Worker?p?=?new?Worker(10L,?"lcy",?18);??//?創(chuàng)建一個(gè)輸出流??ObjectOutputStream?oos?=?new?ObjectOutputStream(??new?FileOutputStream(file)??);??//?輸出可序列化對象??oos.writeObject(p);??//?關(guān)閉輸出流??oos.close();??ObjectInputStream?ois?=?new?ObjectInputStream(new?FileInputStream(file));??Object?newWorker?=?ois.readObject();?//?父類沒有序列化的時(shí)候,需要調(diào)用父類的無參數(shù)構(gòu)造方法??ois.close();??System.out.println(newWorker);??}

    再次測試運(yùn)行

    圖片

    結(jié)果顯示沒有有效地構(gòu)造器,原來是因?yàn)楦割悰]有序列化的時(shí)候,Object newWorker = ois.readObject()需要直接調(diào)用父類的無參數(shù)構(gòu)造方法,不經(jīng)過子類的無參構(gòu)造方法。

    我們在父類People中加上空的構(gòu)造方法之后再次執(zhí)行

    圖片

    結(jié)果卻發(fā)現(xiàn)打印的不是Worker,而是父類People,因?yàn)樽宇悰]有實(shí)現(xiàn)toString而調(diào)用父類的toString,所以打印了People對象,至于父類成員變量id為什么是null,原因如下:

    1、一個(gè)子類實(shí)現(xiàn)了 Serializable 接口,它的父類都沒有實(shí)現(xiàn) Serializable接口,序列化該子類對象。要想反序列化后輸出父類定義的某變量的數(shù)值,就需要讓父類也實(shí)現(xiàn)Serializable接口或者父類有默認(rèn)的無參的構(gòu)造函數(shù)。

    2、在父類沒有實(shí)現(xiàn)Serializable 接口時(shí),虛擬機(jī)是不會序列化父對象的,而一個(gè) Java對象的構(gòu)造必須先有父對象,才有子對象,反序列化也不例外。所以反序列化時(shí),為了構(gòu)造父對象,只能調(diào)用父類的無參構(gòu)造函數(shù)作為默認(rèn)的父對象。因此當(dāng)我們?nèi)「笇ο蟮淖兞恐禃r(shí),它的值是調(diào)用父類無參構(gòu)造函數(shù)后的值,如果在父類無參構(gòu)造函數(shù)中沒有對變量賦值,那么父類成員變量值都是默認(rèn)值,如這里的Long型就是null。

    3、根據(jù)以上特性,我們可以將不需要被序列化的字段抽取出來放到父類中,子類實(shí)現(xiàn) Serializable接口,父類不實(shí)現(xiàn)Serializable接口但提供一個(gè)空構(gòu)造方法,則父類的字段數(shù)據(jù)將不被序列化。

    最后加上子類Worker的toString方法,打印結(jié)果如下:

    圖片

    總結(jié):

    • 子類實(shí)現(xiàn)Serializable接口,父類沒有實(shí)現(xiàn),子類可以序列化!!

    • 這種情況父類一定要提供空構(gòu)造方法,不要忘了子類的toString方法!

    3.類中存在引用對象,這個(gè)類對象在什么情況下可以實(shí)現(xiàn)序列化?

    來一個(gè)組合對象,里面引用People對象,此時(shí)People對象沒有實(shí)現(xiàn)Serializable接口,能否序列化呢?代碼給出來,大家可以自行復(fù)制測試一下。

    public?class?Combo?implements?Serializable?{??private?int?id;??private?People?people;??public?Combo(int?id,?People?people)?{??this.id?=?id;??this.people?=?people;??}??public?int?getId()?{??return?id;??}??public?void?setId(int?id)?{??this.id?=?id;??}??public?People?getPeople()?{??return?people;??}??public?void?setPeople(People?people)?{??this.people?=?people;??}??@Override??public?String?toString()?{??return?"Combo{"?+??"id="?+?id?+??",?people="?+?people?+??'}';??}?? }public?class?People?{??private?Long?id;??public?People()?{??}??public?People(Long?id)?{??this.id?=?id;??}??public?Long?getId()?{??return?id;??}??public?void?setId(Long?id)?{??this.id?=?id;??}??@Override??public?String?toString()?{??return?"People{"?+??"id="?+?id?+??'}';??}?? }private?static?void?testSerializableCombo()?throws?Exception?{??File?file?=?new?File("/tmp/combo_10.java_");??if?(!file.exists())?{??//?1,先得到文件的上級目錄,并創(chuàng)建上級目錄??file.getParentFile().mkdirs();??try?{??//?2,再創(chuàng)建文件??file.createNewFile();??}?catch?(IOException?e)?{??e.printStackTrace();??}??}??Combo?p?=?new?Combo(1,?new?People(10L));??//?創(chuàng)建一個(gè)輸出流??ObjectOutputStream?oos?=?new?ObjectOutputStream(??new?FileOutputStream(file)??);??//?輸出可序列化對象??oos.writeObject(p);??//?關(guān)閉輸出流??oos.close();??ObjectInputStream?ois?=?new?ObjectInputStream(new?FileInputStream(file));??Object?newCombo?=?ois.readObject();??ois.close();??System.out.println(newCombo);??}??public?static?void?main(String[]?args)?throws?Exception?{??testSerializableCombo();??}

    運(yùn)行結(jié)果如下

    圖片

    直接爆出異常,說明People類沒有序列化。

    當(dāng)People加上implements Serializable實(shí)現(xiàn)序列化接口后,再次執(zhí)行如下

    圖片

    總結(jié):

    • 一個(gè)類里面所有的屬性必須是可序列化的,這個(gè)類才能順利的序列化。

    比如,類中存在引用對象,那么這個(gè)引用對象必須是可序列化的,這個(gè)類才能序列化。

    4.同一個(gè)對象多次序列化之間有屬性更新,前后的序列化有什么區(qū)別?

    下面例子中People是可序列化的,每次序列化之前都會把People的id值修改了,用來觀察看看,多次序列化期間,如果對象屬性更新,是否會影響序列化,反序列化有什么區(qū)別。

    /**??*?<h2>同一個(gè)對象多次序列化的問題,?坑</h2>??*?*/?? private?static?void?sameObjectRepeatedSerialization()?throws?Exception?{??File?file?=?new?File("/tmp/peopele_more.java_");??if?(!file.exists())?{??//?1,先得到文件的上級目錄,并創(chuàng)建上級目錄??file.getParentFile().mkdirs();??try?{??//?2,再創(chuàng)建文件??file.createNewFile();??}?catch?(IOException?e)?{??e.printStackTrace();??}??}??People?p?=?new?People(10L);??ObjectOutputStream?oos?=?new?ObjectOutputStream(new?FileOutputStream(file));??//?未序列化,先修改屬性??p.setId(11L);??oos.writeObject(p);??//?序列化一次后,再次修改屬性??p.setId(15L);??oos.writeObject(p);??//?序列化兩次后,再次修改屬性??p.setId(20L);??oos.writeObject(p);??oos.close();??ObjectInputStream?ois?=?new?ObjectInputStream(new?FileInputStream(file));??Object?people1?=?ois.readObject();??Object?people2?=?ois.readObject();??Object?people3?=?ois.readObject();??ois.close();??System.out.println(((People)?people1).getId());??System.out.println(((People)?people2).getId());??System.out.println(((People)?people3).getId());?? }??public?static?void?main(String[]?args)?throws?Exception?{??sameObjectRepeatedSerialization();?? }

    運(yùn)行結(jié)果如下

    圖片

    結(jié)果發(fā)現(xiàn)反序列化讀出的值都是一樣的。說明當(dāng)對象第一次序列化成功后,后續(xù)這個(gè)對象屬性即使有修改,也不會對后面的序列化造成成影響。

    這其實(shí)是序列化算法的原因,所有要序列化的對象都有一個(gè)序列化的編碼號,當(dāng)試圖序列化一個(gè)對象,會檢查這個(gè)對象是否已經(jīng)序列化過,若從未序列化過,才會序列化為字節(jié)序列去輸出。若已經(jīng)序列化過,則會輸出一個(gè)編碼符號,不會重復(fù)序列化一個(gè)對象。如下

    圖片

    序列化一次后,后續(xù)繼續(xù)序列化并未重復(fù)轉(zhuǎn)換為字節(jié)序列,而是輸出字符q~

    總結(jié):

    • 當(dāng)?shù)谝淮涡蛄谢?#xff0c;不管如何修改這個(gè)對象的屬性,都不會對后續(xù)的序列化產(chǎn)生影響,反序列化的結(jié)果都和第一次相同。

    感謝閱讀,希望對你有所幫助?:)?

    來源:liuchenyang0515.blog.csdn.net/

    article/details/118463573

    推薦文章1、一款高顏值的 SpringBoot+JPA 博客項(xiàng)目2、超優(yōu) Vue+Element+Spring 中后端解決方案3、推薦幾個(gè)支付項(xiàng)目!4、推薦一個(gè) Java 企業(yè)信息化系統(tǒng)5、一款基于 Spring Boot 的現(xiàn)代化社區(qū)(論壇/問答/社交網(wǎng)絡(luò)/博客)

    總結(jié)

    以上是生活随笔為你收集整理的实现序列化与反序列化,一定要绕开这些坑!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 欧美精品系列 | 毛片毛片毛片毛片毛片毛片毛片 | 成人精品免费网站 | 美女在线观看视频 | 福利在线国产 | 97caop| 污到下面流水的视频 | 日产电影一区二区三区 | 久久国内免费视频 | 99视频国产精品 | av作品在线 | 国产欧美日韩精品在线观看 | wwww在线观看 | 人妻无码一区二区三区久久 | 欧美成人精品欧美一级 | 免费高清欧美大片在线观看 | 国产成人亚洲欧洲在线 | 大桥未久中文字幕 | 久久加勒比 | 日本色影院 | 污污视频免费看 | 关之琳三级全黄做爰在线观看 | 欧美日韩中文国产一区发布 | 黄色免费入口 | 欧美美女在线观看 | 91麻豆产精品久久久久久夏晴子 | 艳妇乳肉豪妇荡乳av无码福利 | 日本中文字幕有码 | 视频一区日韩 | 精品国产乱码久久久久久闺蜜 | 日本视频在线免费 | 久操中文 | 污视频免费网站 | 国产免费高清 | 国产亚洲精品一区二区三区 | 日韩欧美一区二 | 亚洲成年人网站在线观看 | 久久99色| 欧美一卡二卡在线观看 | 一级v片 | 国产免费一级片 | 日本丰满少妇裸体自慰 | 中文综合网 | 欧美日韩视频一区二区 | 韩国主播青草200vip视频 | 欧美日韩在线免费播放 | 黄色三级小说 | 日本韩国在线播放 | 欧美国产成人精品一区二区三区 | 久久中文字幕高清 | 男男gay羞辱feet贱奴vk | 粉嫩av网址 | 日韩免费高清一区二区 | 麻豆av导航| av三级在线观看 | 日本人妻一区 | 久久免费高清视频 | 中文字幕视频一区二区 | 成人福利视频网站 | 亚洲乱色熟女一区二区三区 | 一区二区在线视频播放 | 亚洲hh| 亚洲爽妇网| 亚洲一级色 | 国产成人免费视频网站 | 黄av在线 | aaaa一级片 | 六月激情综合 | 已满十八岁免费观看 | 亚洲片在线观看 | 久久午夜电影 | 亚洲色图欧美 | 中文在线免费看视频 | 日韩高清影院 | 中文字幕第一 | 色婷婷综合久久久久中文一区二区 | 51精品 | 人人干97 | 中国美女黄色 | 丰满双乳秘书被老板狂揉捏 | 久久国产精品波多野结衣av | 精品盗摄一区二区三区 | 国产无遮挡18禁无码网站不卡 | 两性午夜免费视频 | 神宫寺奈绪一区二区三区 | 日本精品人妻无码免费大全 | 日韩一区2区 | 日本黄a三级三级三级 | 日韩毛片网站 | 三浦理惠子av在线播放 | 日韩精品视频一区二区在线观看 | 91官网入口| 91看毛片 | 国产一区二区三区四区五区美女 | 欧美精选一区二区 | 国产色图视频 | 亚洲AV无码精品色 | 欧美一区二区三区精品 | 久夜精品 |