一 点睛
在序列化对象时,为保证在被反序列化时任然具有唯一性,就需要给每个参与序列化的类发一个唯一的“身份证号码”——序列化版本号,那么这个类在后期怎么修改,它的终身代码的版本号都是这个序列化版本。如果不加,JVM给定义的默认序列化版本就会发生变化。此时的序列化版本号是JVM虚拟机自动计算出来的,此时进行反序列化,会因为版本不一致而出现错误。
二 实战——不使用序列化版本
第一步:准备Person类
import java.io.Serializable;
public class Person implements Serializable
{ // 此类的对象可以被序列化
// public static final long serialVersionUID = 42L; // 先把这行代码注释掉
private String name; // 声明name属性
private int age; // 声明age属性
String country = "cn";
public Person(String name, int age ,String country)
{ // 通过构造方法设置属性内容
this.name = name;
this.age = age;
this.country = country;
}
public String toString()
{ // 覆写toString()方法
return "姓名:" + this.name + ";年龄:"
+ this.age + ";国籍:" + this.country;
}
}
第二步:准备序列化该类的代码
import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
public class SerDemo01
{
public static void main(String[] args) throws Exception
{
File f = new File("SerTest.txt");
ObjectOutputStream oos = null;
OutputStream out = new FileOutputStream(f); // 文件输出流
oos = new ObjectOutputStream(out); // 为对象输出流实例化
oos.writeObject(new Person("Tom", 25, "America")); // 保存对象到文件
oos.close(); // 关闭输出
}
}
第三步:准备反序列化该类的代码
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
public class SerDemo02
{
public static void main(String[] args) throws Exception
{
File f = new File("SerTest.txt");
ObjectInputStream ois = null;
InputStream input = new FileInputStream(f); // 文件输入流
ois = new ObjectInputStream(input); // 为对象输出流实例化
Object obj = ois.readObject(); // 读取对象
ois.close(); // 关闭输出
System.out.println(obj);
}
}
第四步:编译前面3个类
E:\Java\Java编程技术大全\范例源码、实战练习答案、赠送资源\范例源码\chap17\范例17-3>javac Person.java
E:\Java\Java编程技术大全\范例源码、实战练习答案、赠送资源\范例源码\chap17\范例17-3>javac SerDemo01.java
E:\Java\Java编程技术大全\范例源码、实战练习答案、赠送资源\范例源码\chap17\范例17-3>javac SerDemo02.java
第五步:运行序列化和反序列代码
E:\Java\Java编程技术大全\范例源码、实战练习答案、赠送资源\范例源码\chap17\范例17-3>java SerDemo01
E:\Java\Java编程技术大全\范例源码、实战练习答案、赠送资源\范例源码\chap17\范例17-3>java SerDemo02
姓名:Tom;年龄:25;国籍:America
到此一切正常
第六步:修改Person类
import java.io.Serializable;
public class Person implements Serializable
{ // 此类的对象可以被序列化
// public static final long serialVersionUID = 42L;
/*private*/ String name; // 声明name属性,将改属性变成包属性,这样序列化版本号势必发生变化
private int age; // 声明age属性
String country = "cn";
public Person(String name, int age ,String country)
{ // 通过构造方法设置属性内容
this.name = name;
this.age = age;
this.country = country;
}
public String toString()
{ // 覆写toString()方法
return "姓名:" + this.name + ";年龄:"
+ this.age + ";国籍:" + this.country;
}
}
第七步:编译修改后的Person类
第八步:再次运行反序列化类,出现下面错误,这是因为JVM前后编译Person.java文件,序列化版本不一致造成的。
Exception in thread "main" java.io.InvalidClassException: Person; local class incompatible: stream classdesc serialVersionUID = -6046497872633801793, local class serialVersionUID = 2025680955162109577
at java.io.ObjectStreamClass.initNonProxy(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at SerDemo02.main(SerDemo02.java:25)