您的位置:首页 > 产品设计 > UI/UE

SerialVersionUID是什么,有什么作用

2014-09-18 16:18 477 查看
问题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