Java SerialVersionUID作用詳解
問題1:Serializable是什么
首先,說說Serializable是實現(xiàn)java將內(nèi)存中的類存儲至硬盤中而使用的
一個類使用了Serializalbe接口,在序列化到文件時,會有一個SerialVersionUID。
這個東東是用于對類進行版本控制的。
首先看Person類清單:
=====
import java.io.Serializable;
public class Person implements Serializable {
//如果沒有指定serialVersionUID,系統(tǒng)會自動生成一個
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,因此系統(tǒng)自動生成了一個serialVersionUID(這個是根據(jù)類名,變量名,方法名)生成的
但是改動后的Person中變量名有變動,于是這個UID就不一樣了,對于版本控制就無法讀取。
所以,大家在很多代碼里看到把UID設(shè)置為1L,就是Person代碼中那樣。
將Person代碼UID設(shè)置為1L,再重復(fù)上述步驟,不報錯。那么就意味著如果你選擇將UID設(shè)置為1L,就是選擇了兼容類的版本不一致。
PS:為什么說自動生成的 serialVersionUID是根據(jù) 類名,變量名,方法名,因為當(dāng)你在原有的類的方法內(nèi)進行添加內(nèi)容,并不是對最后系統(tǒng)生成的UID造成影響,即不會拋出錯誤
問題2:所有類都設(shè)置為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);
運行結(jié)果拋出錯誤:
Exception in thread "main" java.lang.ClassCastException: serializable.Person cannot be cast to serializable.Dog
說明serializable在不同類一間并不矛盾。
到此這篇關(guān)于Java SerialVersionUID作用詳解的文章就介紹到這了,更多相關(guān)Java SerialVersionUID內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
spring中@Configuration和@Bean注解的用法
這篇文章主要介紹了spring中@Configuration和@Bean注解的用法,@Configuration用于定義配置類,可替換xml配置文件,被注解的類內(nèi)部包含有一個或多個被@Bean注解的方法,需要的朋友可以參考下2023-05-05
如何通過自定義spring?invalidator注解校驗數(shù)據(jù)合法性
這篇文章主要介紹了如何通過自定義spring?invalidator注解校驗數(shù)據(jù)合法性,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07
Intellij?IDEA?的maven項目通過Java代碼實現(xiàn)Jetty的Http服務(wù)器(推薦)
Jetty是一個輕量級的高度可擴展的基于 java的web服務(wù)器和servlet引擎,這篇文章主要介紹了Intellij?IDEA?的maven項目通過Java代碼實現(xiàn)?Jetty?的?Http服務(wù)器從而獲取到 Http 的 Get 和 Post 請求,需要的朋友可以參考下2022-07-07
springboot?去掉netflix?禁用Eureka的解決方法
這篇文章主要介紹了springboot?去掉netflix?禁用Eureka的解決方法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-09-09
java Hibernate save()與persist()區(qū)別
本文章來給各位同學(xué)介紹一下Hibernate save()與persist()區(qū)別,希望此文章能對各位同學(xué)對于Hibernate save()與persist()有所理解2016-01-01
基于java+springboot+mybatis+laiyu實現(xiàn)學(xué)科競賽管理系統(tǒng)
這篇文章主要介紹了基于java+springboot+mybatis+laiyu實現(xiàn)的學(xué)科競賽管理系統(tǒng),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-09-09

