Java|Java SerialVersionUID作用详解

问题1:Serializable是什么
首先,说说Serializable是实现java将内存中的类存储至硬盘中而使用的
一个类使用了Serializalbe接口,在序列化到文件时,会有一个SerialVersionUID。
这个东东是用于对类进行版本控制的。
首先看Person类清单:
=====

importjava.io.Serializable; publicclassPersonimplementsSerializable {//如果没有指定serialVersionUID,系统会自动生成一个privatestaticfinallongserialVersionUID = 1L; privateString name; //添加这么一个成员变量privateString address; //序列化后如果之前版本没有,就为null publicString getName() {//int a = 100; //for(int i=0; i ===== 然后是测试类清单 =====
importjava.io.FileInputStream; importjava.io.FileNotFoundException; importjava.io.FileOutputStream; importjava.io.IOException; importjava.io.ObjectInputStream; importjava.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*/publicclassWhySerialversionUID { publicstaticvoidobjectToFile(Object obj,String fileName)throwsException{ObjectOutputStream oo =newObjectOutputStream( newFileOutputStream(fileName)); oo.writeObject(obj); oo.close(); } publicstaticObject getObjectFromFile(String fileName)throwsException {ObjectInputStream oi =newObjectInputStream( newFileInputStream(fileName)); Person crab_back = (Person) oi.readObject(); oi.close(); returncrab_back; }publicstaticvoidmain(String[] args)throwsException {String fileName ="crab_file" ; //文件名// 这里是把对象序列化到文件Person crab =newPerson(); 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,是否有不良影响,不同类会不会冲突
publicclassDogimplementsSerializable{privatestaticfinallongserialVersionUID = 1L; privateString name; publicString getName() {returnname; } publicvoidsetName(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|Java SerialVersionUID作用详解】到此这篇关于Java SerialVersionUID作用详解的文章就介绍到这了,更多相关Java SerialVersionUID内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    推荐阅读