看了一篇简单介绍serialVersionUID的文章,在这里结合javaAPI文档和自己的理解说一下Serializable和serialVersionUID。
一、Serializable
在JavaAPI中已经将这个问题说的很明白了,下面只是简单的概括一下。
1、Serializable是一个标志性接口,没有任何成员变量和方法。需要序列化一个类时只需要声明实现这个接口即可。
2、如果类A中组合了类B的对象的化,序列化类A对象的同时会序列化类B对象,前提是类A和类B都实现了Serializable接口。
3、如果类B继承类A,那么序列化类B分为下面两中情况:
(1)类A没有实现Serializable接口,而类B实现了。那么根据JavaAPI中的说明,如果需要序列化类B,需要保证类A和类B都有无参的构造方法,如果无法默认构造,则必须显式声明。没有无参构造方法的话,在运行时会报异常。
用这种方式试了一下,虽然可以序列化类A继承来的属性(public、protected、包访问),但是不能正确读取,读出来是null,类B自身特有的属性没问题。有待进一步验证。
(2)类A实现了Serializable接口(类B实不实现无所谓,因为继承类A)。通过类B给继承于类A的变量和自身特有的变量赋值,并进行序列化。序列化成功,并可以正确读取。
二、serialVersionUID
serialVersionUID用于可序列化类的版本控制。如果不显式的声明一个serialVersionUID,JVM会基于这个序列化类的不同方面特征自动生成一个。
具体的可以参见JavaAPI文档的Serializable接口说明。
下面用一个例子来说明serialVersionUID的版本控制作用。
下面的类实现了Serializable接口,并且自定义了serialVersionUID=1L
public class Address implements Serializable{
private static final long serialVersionUID = 1L;
String street;
String country;
public void setStreet(String street){
this.street = street;
}
public void setCountry(String country){
this.country = country;
}
public String getStreet(){
return this.street;
}
public String getCountry(){
return this.country;
}
@Override
public String toString() {
return new StringBuffer(" Street : ")
.append(this.street)
.append(" Country : ")
.append(this.country).toString();
}
}
WriteObject类将Address类的对象写入磁盘文件address.ser。
public class WriteObject{
public static void main (String args[]) {
Address address = new Address();
address.setStreet("wall street");
address.setCountry("united state");
try{
FileOutputStream fout = new FileOutputStream("c:\\address.ser");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(address);
oos.close();
System.out.println("Done");
}catch(Exception ex){
ex.printStackTrace();
}
}
}
ReadObject类读取保存了Address对象的文件address.ser
public class ReadObject{
public static void main (String args[]) {
Address address;
try{
FileInputStream fin = new FileInputStream("c:\\address.ser");
ObjectInputStream ois = new ObjectInputStream(fin);
address = (Address) ois.readObject();
ois.close();
System.out.println(address);
}catch(Exception ex){
ex.printStackTrace();
}
}
}
测试类
public class SerialSample {
public static void main(String[] args) {
WriteObject wo=new WriteObject();
ReadObject ro=new ReadObject();
wo.write();
ro.read();
}
}
运行测试类,控制台的显示可以知道对象被序列化存入磁盘文件并正确的读出。下面在Address类中修改serialVersionUID=2L。注释掉测试类中wo.write()这一句并再次执行。控制台出现下面的错误:
java.io.InvalidClassException: *.*.*.Address; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
这是因为序列化的时候serialVersionUID=1L,修改之后我们把一个serialVersionUID=2L的声明引用指向了反序列化后的serialVersionUID=1L的对象。JVM发现了不匹配,所以报错。
这也说明了serialVersionUID在序列化和反序列化的过程中必须匹配。
缺省serialVersionUID。
如果不显式的指定一个serialVersionUID,JVM会根据自有的算法来生成一个缺省的serialVersionUID。
这个缺省的serialVersionUID的计算对类的细节高度敏感,并且会因为不同的JVM而发生变化。在不同的JVM之间进行反序列化会导致InvalidClassExceptions异常。
分享到:
相关推荐
序列化 serializable demo ! 序列化 serializable demo !
說明如何將Serializable物件轉成stream
Serializable的增删改查操作,已经经过验证,可以直接运行。
java->serializable深入了解 java->serializable深入了解 java->serializable深入了解
Laravel开发-serializable-values Luminark可序列化值包。
(1) Construct the precedence graph for S. (2) Is S a serializable schedule (3) I
Item 38: Understand the Pros and Cons of Dynamic 227 Item 39: Use Dynamic to Leverage the Runtime Type of Generic Type Parameters 236 Item 40: Use Dynamic for Parameters That Receive Anonymous Types ...
Java_Serializable(序列化) 的理解和总结
Intent传递数据是android开发中最长用的数据传递方式,可是要传递对象不怎么常用,这里介绍第一种传递对象的方法Serializable传递
java.io.Serializable序列化问题
详细讲解了C#中关于对象序列化的知识,包括基本序列化、选择序列化、自定义序列化;对于了解在C#中如何进行对象的序列化有价值
bundle传递基本数据,Parcelable类型数据,Serializable类型数据
Android序列化——Serializable与Parcelable
java 序列化 对象 Serializable 写着玩的Demo 简单 实用
Prior to delivering this material, test the class to see if they fully understand the different isolation levels. If the class is not confident in their understanding, review appendix A04_Locking and ...
Android中的Serializable
java 将对象序列化 输出对象的值,不懂可以百度序列化干啥的,为什么要用序列化,好处。
[Serializable]在C_中的作用-NET_中的对象序列化,希望有所帮助
or add a few lines of code to your existing class, and everything serializable shall be serialized. Yes, even polymorphic types! Odin serialized prefabs are deprecated in 2018.3+ due to
java序列化(Serializable)的作用和反序列化.doc 有详细的讲解哦。 在什么地方用的到都有说明的.