serialversionuid的作用_为什么阿里Java规约要求谨慎修改serialVersionUID字段
serialVersionUID簡(jiǎn)要介紹
serialVersionUID是在Java序列化、反序列化對(duì)象時(shí)起作用的一個(gè)字段。Java的序列化機(jī)制是通過(guò)判斷類的serialVersionUID來(lái)驗(yàn)證版本一致性的。在進(jìn)行反序列化時(shí),JVM會(huì)把傳來(lái)的字節(jié)流中的serialVersionUID與本地相應(yīng)實(shí)體類的serialVersionUID進(jìn)行比較,如果相同就認(rèn)為是一致的,可以進(jìn)行反序列化,否則就會(huì)出現(xiàn)序列化版本不一致的異常,即是InvalidClassException。
序列化是一種把對(duì)象持久化到外部的手段。在網(wǎng)絡(luò)傳輸?shù)葓?chǎng)景中應(yīng)用廣泛,如Dubbo等框架。類通過(guò)實(shí)現(xiàn) java.io.Serializable 接口以啟用其序列化功能。
阿里Java規(guī)約中的描述
阿里規(guī)約中強(qiáng)制性的提醒,修改serialVersionUID字段,會(huì)引起反序列化失敗的情況。
代碼演示
下面,通過(guò)實(shí)際代碼,來(lái)演示對(duì)象序列化、反序列化的操作。
引入依賴
org.apache.commons commons-lang3 3.8.1commons-io commons-io 2.6junit junit 4.12commons-lang3這個(gè)包有幫我們實(shí)現(xiàn)了序列化的工具類,commons-io幫我們實(shí)現(xiàn)了文件操作的工具類,junit用來(lái)寫單元測(cè)試。
序列化
有User.class如下:
@Data@Builderpublic class User implements Serializable {? private static final long serialVersionUID = 1L;? private String username;?}@Data 和 @Builder 是Lombok里面的注解,可以自動(dòng)生成getter、setter方法等,不懂的可以查看我之前的文章,對(duì)這個(gè)有講解。
需要序列化的類,需要實(shí)現(xiàn)Serializable接口,Serializable是一個(gè)標(biāo)識(shí)接口,里面沒(méi)有具體需要實(shí)現(xiàn)的東西。
序列化代碼:
@Testpublic void serializeTest() throws IOException { User user = User.builder().username("happyjava").build(); byte[] serialize = SerializationUtils.serialize(user); FileUtils.writeByteArrayToFile(new File("serialize.txt"), serialize);}SerializationUtils是commons-lang3包給我們提供的工具類,它給我們提供了序列化和反序列化的方法,我們直接拿過(guò)來(lái)用就好了。
FileUtils是commons-io包給我們提供的工具類,它給我們提供了非常豐富的IO操作工具類。
執(zhí)行方法后,查看serialize.txt:
這就是序列化后,保存到外部的對(duì)象了。我們可以把它反序列化成為對(duì)象。
反序列化
反序列化代碼如下:
@Testpublic void deserializeTest() throws IOException { byte[] bytes = FileUtils.readFileToByteArray(new File("serialize.txt")); Object object = SerializationUtils.deserialize(bytes); System.out.println(object instanceof User); User user = (User)object; System.out.println(user.getUsername());}這里使用FileUtils把外部的文件讀入,使用SerializationUtils反序列化成為對(duì)象。然后判斷反序列化后對(duì)象的類型,強(qiáng)轉(zhuǎn)為User后輸出其username,運(yùn)行結(jié)果如下:
說(shuō)明反序列化已經(jīng)成功過(guò)了
修改serialVersionUID值,使反序列化異常
現(xiàn)在把User的serialVersionUID值做一下修改:
@Data@Builderpublic class User implements Serializable {? private static final long serialVersionUID = 2L;? private String username;?}之前是1,現(xiàn)在改為2,再次執(zhí)行反序列化方法,結(jié)果如下:
這里出現(xiàn)了開(kāi)頭提到的InvalidClassException異常,并且通過(guò)異常信息可以看到,這是serialVersionUID不一致引起的。
org.apache.commons.lang3.SerializationException: java.io.InvalidClassException: cn.happy.User; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2總結(jié)
通過(guò)理論和代碼演示,我們已經(jīng)知道了serialVersionUID字段可以造成反序列化失敗的情況。所以在做系統(tǒng)升級(jí)的時(shí)候,需要充分考慮是否要改動(dòng)serialVersionUID的值,因?yàn)檫@會(huì)引起兼容性的問(wèn)題。
總結(jié)
以上是生活随笔為你收集整理的serialversionuid的作用_为什么阿里Java规约要求谨慎修改serialVersionUID字段的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 有效沟通力思维导图
- 下一篇: Web前端书单从HTML到JS到AJAX