SerialVersionUID是什么,有什么作用
2014-09-18 16:18
477 查看
问题1:Serializable是什么
首先,说说Serializable是实现java将内存中的类存储至硬盘中而使用的
一个类使用了Serializalbe接口,在序列化到文件时,会有一个SerialVersionUID。
这个东东是用于对类进行版本控制的。
首先看Person类清单:
=====
=====
然后是测试类清单
=====
2.将变量address还原,读取原来存储的文件,显示异常。抛出错误InvalidClassException。
原因如下:
因为我们没有指定SerialVersionUID,因此系统自动生成了一个serialVersionUID(这个是根据类名,变量名,方法名)生成的
但是改动后的Person中变量名有变动,于是这个UID就不一样了,对于版本控制就无法读取。
所以,大家在很多代码里看到把UID设置为1L,就是Person代码中那样。
将Person代码UID设置为1L,再重复上述步骤,不报错。那么就意味着如果你选择将UID设置为1L,就是选择了兼容类的版本不一致。
PS:为什么说自动生成的serialVersionUID是根据类名,变量名,方法名,因为当你在原有的类的方法内进行添加内容,并不是对最后系统生成的UID造成影响,即不会抛出错误
问题2:所有类都设置为1L,是否有不良影响,不同类会不会冲突
运行结果抛出错误:
Exception in thread "main" java.lang.ClassCastException: serializable.Person cannot be cast to serializable.Dog
说明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在不同类一间并不矛盾。
相关文章推荐
- 什么是serialVersionUID,serialVersionUID的作用
- 【转载】serialVersionUID有什么作用
- java 序列化定义的 serialVersionUID 有什么作用
- serialVersionUID作用
- serialVersionUID的作用
- serialVersionUID的作用
- serialVersionUID作用
- serialVersionUID的作用
- serialVersionUID作用
- serialVersionUID作用
- serialVersionUID的作用
- serialVersionUID的作用以及如何用idea自动生成实体类的serialVersionUID
- serialVersionUID的作用
- serialVersionUID的作用
- serialVersionUID的作用
- serialVersionUID的作用
- serialVersionUID作用
- 常见MyEclipse报错—— serialVersionUID的作用
- Q:java中serialVersionUID的作用
- eclipse3.2中serialVersionUID的作用