国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

你知道為什么序列化要寫serialVersionUID嗎?

開發 前端
Externalizable?接口想必大家很少用到,它是Serializable?接口的子類,用戶要實現的writeExternal()和readExternal() 方法,用來決定如何序列化和反序列化。

?前言

java中的序列化可能大家像我一樣都停留在實現Serializable?接口上,對于它里面的一些核心機制沒有深入了解過。直到最近在項目中踩了一個坑,就是序列化對象添加一個字段以后,使用方系統報了反序列化失敗,原因是我們雙方的序列化對象沒有加上serialVersionUID,那你們知道下面幾個問題嗎:

  1. 序列化對象中的serialVersionUID 是干嘛用的?
  2. 如何修改默認的序列化機制?
  3. 如何使用序列化的方式克隆對象?

對象序列化和反序列化機制

序列化: 將對象轉成二進制寫到輸出流的過程。

反序列化: 通過輸入流讀回二進制轉成對象的過程。

通過對象的序列化和反序列化機制可以實現對象在網絡之間傳輸。

在Java中,如果一個對象要想實現序列化,必須要實現下面兩個接口之一:

  • Serializable 接口
  • Externalizable 接口

這里我們先講解常用的Serializable 接口。

writeObject序列化過程栗子:

@Test
public void testSerializable() throws FileNotFoundException {
User user = new User("alvin", 19);
// 文件輸出流
FileOutputStream bout = new FileOutputStream("user.dat");
try (ObjectOutputStream out = new ObjectOutputStream(bout)) {
// 序列化
out.writeObject(user);
} catch (IOException e) {
e.printStackTrace();
}
}


@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {

private String username;

private Integer age;
}

結果:

圖片

readObject反序列化栗子:

現在模擬另外一個系統需要反序列化user.dat

@Test
public void testDeSerializable() throws FileNotFoundException {
User user = null;
// 寫到內存中,當然也可以寫到文件中
FileInputStream fis = new FileInputStream("user.dat");
try (ObjectInputStream in = new ObjectInputStream(fis)) {
// 反序列化 readObject
user = (User) in.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}

Assert.assertEquals("alvin", user.getUsername());
}

如果User類不實現Serializable接口, 那會怎么樣?

當然是報錯了,如下圖:

圖片

小結:

一個對象想要被序列化,那么它的類就要實現此接口或者它的子接口。

修改默認的序列化機制

默認的情況下,如果實現了Serializable接口的對象進行序列化的時候,默認會將全部的數據域,也就是成員變量進行序列化輸出,那往往有時候并不需要這樣,有什么方法可以修改序列化機制呢?下面提供3種方式。

使用transient關鍵字

將成員變量標記成transient,那么在序列化的過程中這些數據域會被跳過,如下圖所示:

圖片

這是一種最簡單的方式,但是不夠靈活。

自定義readObject、writeObject方法

序列化類中可以通過定義下面簽名的方法:

  • private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException
  • private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException

只要類中有這兩個簽名的方法,那么就不會調用默認的序列化,取而代之調用這些方法。

本例我們舉個jdk中的例子,ArrayList就實現了這兩個方法,重寫了序列化機制。

圖片

主要原因ArrayList底層的數組通常會預留一些容量,等容量不足時再擴充容量,那么有些空間可能就沒有實際存儲元素,采用自定義方式實現序列化時,就可以保證只序列化實際存儲的那些元素,而不是整個數組,從而節省空間和時間。

實現Externalizable接口

Externalizable?接口想必大家很少用到,它是Serializable?接口的子類,用戶要實現的writeExternal()和readExternal() 方法,用來決定如何序列化和反序列化。

因為序列化和反序列化方法需要自己實現,因此可以指定序列化哪些屬性,而transient在這里無效。

對Externalizable?對象反序列化時,會先調用類的無參構造方法,這是有別于默認反序列方式的。如果把類的不帶參數的構造方法刪除,或者把該構造方法的訪問權限設置為private?、默認或protected?級別,會拋出java.io.InvalidException: no valid constructor?異常,因此Externalizable?對象必須有默認構造函數,而且必需是public的。

舉例說明:

public class User2 implements Externalizable {

private String username;

private Integer age;

@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeUTF(username);
out.writeInt(age);
}

@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
username = in.readUTF();
age = in.readInt();
}
}

serialVersionUID的作用

這就回到概述中提到的項目中遇到的問題,現在簡要描述下:

A系統中的序列化對象User用的最新版本如下:

圖片

B系統中反序列化的對象,還是老的User版本如下:

圖片

這時候A系統生成的序列化文件,交給B系統反序列化時,出錯了, 如下圖:

圖片

原因:

類定義發生了變化,比如添加、刪除、修改類中的數據域后,它的唯一標記符或者稱為SHA指紋、或者理解為serialVersionUID都會發生變化,這個值會保存在序列化二進制中,如果反序列化過程發現對不上,就會報錯,如上圖所示。

那么如何處理呢?

這時候,我們如果覺得這個序列化對象是可以兼容的,那么可以自定義一個serialVersionUID的靜態成員變量,它就不會自動生成,而是直接用這個值,如下圖:

圖片

使用序列化clone

clone大家都知道吧,在深拷貝的時候編碼還是很麻煩的,借用序列化機制可以實現深拷貝。做法很簡單,就是將對象序列化到輸出流中,然后讀回。

public class SerialCloneable implements Cloneable, Serializable {

@Override
public Object clone() throws CloneNotSupportedException {
try {
// 保存到字節數組流
ByteArrayOutputStream bout = new ByteArrayOutputStream();
try(ObjectOutputStream out = new ObjectOutputStream(bout)) {
out.writeObject(this);
}
// 讀取
try(InputStream bin = new ByteArrayInputStream(bout.toByteArray())) {
ObjectInputStream in = new ObjectInputStream(bin);
return in.readObject();
}
} catch (IOException | ClassNotFoundException e) {
CloneNotSupportedException e2 = new CloneNotSupportedException();
e2.initCause(e);
throw e2;
}
}
}

圖片

注意一點,這種方式性能不高,通常比顯示構建、復制數據要慢不少。

總結

本文講解了序列化的一些核心機制,不再簡簡單單的停留在序列化就是實現Serializable接口了,希望能幫助到大家。

責任編輯:武曉燕 來源: JAVA旭陽
相關推薦

2024-04-03 09:23:31

ES索引分析器

2018-10-28 15:40:23

Python編程語言

2023-06-26 08:20:02

openapi格式注解

2023-09-08 08:35:42

層疊樣式表CSS

2014-07-15 11:05:30

黑莓

2020-12-30 05:33:30

Java網絡數據

2011-06-01 15:18:43

Serializabl

2020-12-24 18:46:11

Java序列化編程語言

2024-09-03 08:17:59

2024-12-02 12:34:06

2020-11-17 08:30:06

LinuxSwapping 設計

2025-05-08 08:30:00

Redis自定義序列化數據庫

2023-11-02 10:22:29

gRPC后端通信

2024-10-09 08:19:35

2022-08-06 08:41:18

序列化反序列化Hessian

2025-04-30 10:49:11

Java序列化反序列化

2025-03-05 10:49:32

2019-12-09 10:29:04

Go語言開發互聯網

2025-06-05 01:11:00

2020-04-16 11:19:55

深度學習神經網絡網絡層
點贊
收藏

51CTO技術棧公眾號

91嫩草视频在线观看| 久久aⅴ国产欧美74aaa| 夜夜嗨av一区二区三区| 日韩久久久久久久久久久久久| 亚洲视频国产| 欧美日韩www| 国产二区三区四区| 国产美女精品一区二区三区| 成人免费在线视频网站| 精品中文字幕一区二区三区四区| 欧美高清精品3d| 黄污在线观看| 久久精品欧美一区二区三区不卡 | 久久亚洲影音av资源网| 欧美三级电影一区二区三区| 国产女人18水真多18精品一级做| 亚洲国产一区二区三区在线播| 99精品视频在线观看免费播放 | 亚洲黄色视屏| 国产91在线视频| av不卡一区二区| 日韩视频一区在线| 成人性教育av免费网址| 欧美日韩久久不卡| 中文字幕在线看| 一区二区三区丝袜| 日本成人免费| 成人免费一区二区三区视频 | melody高清在线观看| 亚洲午夜视频在线观看| 免费高清成人| 欧美激情一区二区三区| 丁香六月激情婷婷| 国产乱码精品一区二区三区忘忧草| 鲁丝片一区二区三区| 国产精品a级| 国产激情美女久久久久久吹潮| 91精品一区国产高清在线gif| 男女精品网站| 亚洲成av人影院在线观看网| 国产美女av| 一区二区三区在线视频观看58| 成人网免费看| 一区二区三区在线播放| 91欧洲在线视精品在亚洲| 亚洲一二三区在线观看| 黄页免费在线观看| 亚洲最大的成人av| 婷婷亚洲一区二区三区| 一本到一区二区三区| 麻豆av电影在线观看| 欧美亚洲国产一区在线观看网站| 91社区在线高清| 欧美一区二区三级| 精品捆绑调教一区二区三区| 精品视频中文字幕| 日韩电影精品| 午夜精品福利在线观看| 中文字幕一区二区三区四区久久| 亚洲japanese制服美女| 裸体在线国模精品偷拍| 狠狠爱一区二区三区| 国产精品996| 国产精品久久9| 日本精品网站| 91精品麻豆日日躁夜夜躁| 在线观影网站| 午夜日韩在线电影| 都市激情在线视频| 精品福利樱桃av导航| 国产成人三级视频| 午夜电影亚洲| 成人区精品一区二区| 污污的视频在线观看| 久久精品亚洲麻豆av一区二区| 亚洲素人一区二区| 久久久一二三四| 国产区在线观看| 国产精品国产一区| 亚洲www在线观看| 国产一区二区三区久久| 中国一级黄色录像| 中文一区二区在线观看| 你懂的视频在线| 日韩精品欧美国产精品忘忧草| 天堂久久一区| 97在线视频免费播放| 国产视频911| 一区二区三区性视频| 成人欧美一区二区三区白人| 国产a亚洲精品| 欧美激情第99页| 国内精品久久久久久久影视麻豆| 亚洲美女搞黄| 欧美激情综合网| 麻豆传媒视频在线观看免费| 日韩在线免费视频观看| 911久久香蕉国产线看观看| 三级网在线观看| 亚洲精品免费在线播放| 国产福利一区在线| 校园春色 亚洲色图| 色一区在线观看| 成人深夜福利| 国产精品久久波多野结衣| 91免费在线看| 精品176二区| 91豆花精品一区| 狠狠色狠狠色综合日日91app| 亚洲精华国产精华| 色先锋资源久久综合5566| 欧美日韩亚洲三区| 明星乱亚洲合成图.com| 亚洲欧洲国产精品| 免费中文字幕日韩欧美| 最新理论片影院| 欧美成人h版在线观看| 久久久成人网| 在线视频观看你懂的| 久久综合色影院| 日韩va亚洲va欧美va久久| 快色在线观看| 久久亚洲精品国产亚洲老地址| 在线一区欧美| 97影视大全免费追剧大全在线观看| 中文字幕av一区| 久久精品30| 嫩草研究院在线| 久久伊人精品一区二区三区| 久久久天天操| 在线观看av中文| 欧美亚洲视频一区二区| 成人精品视频一区| 色黄网站在线观看| 国内精品视频在线播放| 一区二区三区中文字幕在线观看| 日韩精品三区| 亚洲精品在线视频观看| 色综合久久久久久久久久久| 丝袜美腿综合| 国产亚洲精品一区二区| 久久久国产精品一区二区中文| 亚洲男人都懂的网站| 日韩免费精品视频| 国产精品毛片无遮挡高清| 日韩一区二区三区在线免费观看 | 亚洲乱码一区二区三区| 亚洲综合网站在线观看| 国产一区二区在线观| 国产又黄又爽免费视频| 欧美精品电影在线播放| 亚洲理论电影网| 性疯狂做受xxxx高清视频| 欧美激情精品久久久久久蜜臀| 国产成人精品亚洲日本在线桃色| 七七成人影院| 九九99玖玖| 欧美精品 日韩| 中文久久精品| 99re在线视频| 精品免费国产| 欧美精品高清视频| 噜噜噜在线观看免费视频日韩| 国产免费视频在线| 亚洲字幕一区二区| 色综合天天综合网天天狠天天| 成人看的视频| 亚洲精品无码专区在线播放| 国产精品视频久| 日韩欧亚中文在线| 亚洲国产日韩欧美一区二区三区| 六月婷婷激情综合| 中文字幕亚洲一区二区三区| 国产91在线观看| 91麻豆精品| 麻豆一区二区三区视频| 国内精品久久久久影院 日本资源 国内精品久久久久伊人av | 在线免费av一区| 狠狠色综合网| 黄av在线播放| 一区二区冒白浆视频| 亚洲欧美制服中文字幕| 99久久久精品免费观看国产蜜| 亚洲精品在线a| 黄动漫在线免费观看| av免费观看久久| 亚洲精品一区二区三区蜜桃下载| 国产一区二区视频在线| 欧美美女福利视频| 电影天堂爱爱爱爱| 亚洲综合av影视| 亚洲电影天堂av| 久久久久成人黄色影片| 国产一区二区电影在线观看| 免费在线毛片| 亚洲一区二区三区涩| 久久久99久久精品女同性| 亚洲欧美电影院| 亚洲欧洲一区| 亚洲青青一区|