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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java中序列化的serialVersionUID解释

發布時間:2024/1/23 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java中序列化的serialVersionUID解释 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
serialVersionUID: 字面意思上是序列化的版本號,這個在剛剛接觸java編程時,學序列化大家一般都不會注意到,在你一個類序列化后除非你強制去掉了myeclipse中warning的功能,在你實現序列化的類上會有這個警告,點擊會出現增加這個版本號。
說說這個版本號得作用: 就是確保了不同版本之間的兼容性,不僅能夠向前兼容,還能夠向后兼容,即在版本升級時反序列化仍保持對象的唯一性。
它有兩種生成方式:? ? ? ? ? ?
? ? ? ? ? ? 一個是默認的1L,比如:private static final long serialVersionUID = 1L;
?????? 一個是根據類名、接口名、成員方法及屬性等來生成一個64位的哈希字段,比如:? private static final long serialVersionUID = xxxxL;
從兩個例子上來說明這個序列化號的作用:
? ? ? ? ? 這是一個類實現了序列化,但是并沒有顯式的聲明序列號,在這里說明一下,如果沒有顯式聲明序列號,那么在程序編譯時會自己生成這個版本序列號,
? ? ? ? ? 程序1
? ? ? ? ? public class Animal implements Serializable{

? ? ? public String name;

? ? ? public String no;

? ? ?
? ? ? ? }
? ? ? ?
? ? ? ? 通過這個程序來將上面的一個實體存起來:程序2
? ? ? ? public static void main(String[] args) throws Exception{
? ? ? Animal an = new Animal();
? ? ? FileOutputStream f = new FileOutputStream("foo");
? ? ? ObjectOutputStream oos = new ObjectOutputStream(f);
? ? ? oos.writeObject(an);
? ? ? oos.close();
? ? ? ? ? }
? ? ? ? 通過這個程序讀取出剛才存儲的類:程序3
? ? ? ? public static void main(String[] args) throws Exception{
? ? ? ? ? ? ? FileInputStream fis = new FileInputStream("foo");
? ? ? ObjectInputStream ois = new ObjectInputStream(fis);
? ? ?
? ? ? ? ? ? ? Animal ani = (Animal)ois.readObject();
? ? ? ? ? ? ? ois.close();
? ? ? ? ? ? ? fis.close();? ? ?
? ? ? ? }
? ? ? ? 這種編譯是成功的,但是當你在程序1中的類增加一個成員變量的時候,在運行程序3,就會報錯:
? ? ? ? ? Exception in thread "main" java.io.InvalidClassException: koal.Animal;……
? ? ? at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:562)
? ? ? at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1583)
? ? ? at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496)
? ? ? at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732)
? ? ? at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
? ? ? at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
? ? ? at koal.SerialVersion.main(SerialVersion.java:22)
? ? ? 這是為什么呢?
? ? ? 因為在你沒有顯式的聲明序列號時,在程序編譯時候會自動生成一個序列號,存儲在文件中,但是在你更改了實體類的時候又會重新生成一個序列號,在程序運行的時候,Java的序列化機制是通過在運行時判斷類的serialVersionUID來驗證版本一致性的。在進行反序列化時,JVM會把傳來的字節流中的serialVersionUID與本地相應實體(類)的serialVersionUID進行比較,如果相同就認為是一致的,可以進行反序列化,否則就會出現序列化版本不一致的異常。也就是說,在你讀取這個object的時候,他會比較你的現在這個類的序列號和你存儲的那個序列號是否相等,如果相等,則說明這是同一個版本,如果不相等則是不同版本,不同版本之間的成員變量是不相同的,所以就會報錯,但是當你顯式的聲明了這個序列號時,不論你如何修改類中的成員變量還是方法,都不會引起版本之間不兼容得問題,這個就加強了你的程序的健壯性。
? ? ? 在很多地方我們都會用到這個序列化,例如在游戲中,游戲升級之后,還要能夠讓程序成功讀取以前的數據,讓升級之后的程序還能認識以前的數據文件,即使數據格式不一致,也不會丟失數據。
? ? 像一些持久化的配置文件,中途要升級,增加屬性,都要使用這個版本序列號,在這里我們是希望程序中只要是實現序列化的類都最好是顯式的聲明這個序列版本號。

總結

以上是生活随笔為你收集整理的java中序列化的serialVersionUID解释的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。