作为一名Java程序猿,你可能不止一次的在你的代码中加上如下类似代码:
private static final long serialVersionUID = -1621157410689606874L;
但如果有人问你,为什么要这么做?或许有人可能说,IDE强制要求的。
我们都知道序列化和反序列化是怎么回事,简单来讲,Java对象只存在于JVM中,当JVM退出时,对象也会被销毁。序列化就是将对象以字节形式存于他地,也有可能是文件系统。反序列化就是通过这些字节再次将Java对象重新构造出来。但是,这里有一个关键,如何确保在这一过程中保持类不变?这时,我们就需要seriaVersionUID了。
seriaVersionUID就用以在反序列化的过程中验证一个序列化对象的发送方(序列化的人)和接收方(反序列化的人)收到的是同一类对象,即seriaVersionUID是否一致,如果一致,那么我们认为他是同一对象,否则就认为不一致,抛出InvalidClassException异常。
注意:seriaVersionUID必须为static, final, long
我们以一个简单的示例如下:
定义一个Employee类
@Getter
@Setter
@Builder
public class Employee implements Serializable {
private static final long serialVersionUID = -1621157410689606874L;
private String id;
private String name;
private int age;
private String address;
public String whoIsThis() {
StringBuffer employee = new StringBuffer();
employee.append(getName()).append(" is ").append(getAge()).append(" years old and lives at ")
.append(getAddress());
return employee.toString();
}
}
通过Writer将其序列化到文件系统
public class Writer {
public static void main(String[] args) throws IOException {
Employee employee = Employee.builder().name("Ashintha").age(30).address("Galle").build();
FileOutputStream fout = new FileOutputStream("employee.obj");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(employee);
oos.close();
System.out.println("Process complete");
}
}
Process complete
通过Reader将其反序列化出来
public class Reader {
public static void main(String[] args) throws ClassNotFoundException, IOException {
FileInputStream fin = new FileInputStream("employee.obj");
ObjectInputStream ois = new ObjectInputStream(fin);
Employee employee = (Employee) ois.readObject();
ois.close();
System.out.println(employee.whoIsThis());
}
}
Ashintha is 30 years old and lives at Galle
这时,我们修改下Employee的seriaVersionUID,然后直接重新执行Reader,看是否能够对已有序列化文件成功反序列,结果报错:
Exception in thread "main" java.io.InvalidClassException: serialization.Employee; local class incompatible: stream classdesc serialVersionUID = -1621157410689606872, local class serialVersionUID = -1621157410689606874
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:616)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1630)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1521)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1781)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
at serialization.Reader.main(Reader.java:16)
https://dzone.com/articles/what-is-serialversionuid?fromrel=true