Java SerialVersionUID作用詳解
問題1:Serializable是什麼
首先,說說Serializable是實現java將內存中的類存儲至硬盤中而使用的
一個類使用瞭Serializalbe接口,在序列化到文件時,會有一個SerialVersionUID。
這個東東是用於對類進行版本控制的。
首先看Person類清單:
=====
import java.io.Serializable; public class Person implements Serializable { //如果沒有指定serialVersionUID,系統會自動生成一個 private static final long serialVersionUID = 1L; private String name; //添加這麼一個成員變量 private String address; //序列化後如果之前版本沒有,就為null public String getName() { // int a = 100; // for(int i=0;i<a;i++){ // name+=i; // } return name; } public void setName(String name) { this .name = name; } }
===== 然後是測試類清單 =====
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; /** * if Object implements Serializable without Uid, * system will automatically give this object a uid by algorithm * @author v11 * @date 2014年9月18日 * @version 1.0 */ public class WhySerialversionUID { public static void objectToFile(Object obj,String fileName) throws Exception{ ObjectOutputStream oo = new ObjectOutputStream( new FileOutputStream( fileName)); oo.writeObject(obj); oo.close(); } public static Object getObjectFromFile(String fileName) throws Exception { ObjectInputStream oi = new ObjectInputStream( new FileInputStream( fileName)); Person crab_back = (Person) oi.readObject(); oi.close(); return crab_back; } public static void main(String[] args) throws Exception { String fileName = "crab_file" ; //文件名 // 這裡是把對象序列化到文件 Person crab = new Person(); crab.setName( "Mr.Crab" ); //儲存到文件中 //objectToFile(crab,fileName); // 這裡是把對象序列化到文件,我們先註釋掉,一會兒用 Person crabBack = (Person) getObjectFromFile(fileName); //Dog crabBack = (Dog) getObjectFromFile(fileName); System.out.println( "Hi, My name is " + crabBack.getName()); } }
=====
1.對於Person類中,將變量 address和SerialVersionUID註釋掉,存儲到文件,並讀出。顯示正常
2.將變量address還原,讀取原來存儲的文件,顯示異常。拋出錯誤 InvalidClassException。
原因如下:
因為我們沒有指定SerialVersionUID,因此系統自動生成瞭一個serialVersionUID(這個是根據類名,變量名,方法名)生成的
但是改動後的Person中變量名有變動,於是這個UID就不一樣瞭,對於版本控制就無法讀取。
所以,大傢在很多代碼裡看到把UID設置為1L,就是Person代碼中那樣。
將Person代碼UID設置為1L,再重復上述步驟,不報錯。那麼就意味著如果你選擇將UID設置為1L,就是選擇瞭兼容類的版本不一致。
PS:為什麼說自動生成的 serialVersionUID是根據 類名,變量名,方法名,因為當你在原有的類的方法內進行添加內容,並不是對最後系統生成的UID造成影響,即不會拋出錯誤
問題2:所有類都設置為1L,是否有不良影響,不同類會不會沖突
public class Dog implements Serializable{ private static final long serialVersionUID = 1L; private String name; public String getName() { return name; } public void setName(String name) { this .name = name; } }
新定義Dog類如上,將測試類代碼中Dog的賦值註釋去掉
//Dog crabBack = (Dog) getObjectFromFile(fileName);
運行結果拋出錯誤:
Exception in thread “main” java.lang.ClassCastException: serializable.Person cannot be cast to serializable.Dog
說明serializable在不同類一間並不矛盾。
到此這篇關於Java SerialVersionUID作用詳解的文章就介紹到這瞭,更多相關Java SerialVersionUID內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!