在Java中,类可以实现Serializable接口以支持对象的序列化和反序列化。当一个类实现了Serializable接口时,它的对象可以被转换为字节序列,这些字节序列可以在网络上传输,或者保存到磁盘上。反之,这些字节序列也可以被反序列化为对象。
serialVersionUID是一个序列化版本号,它用于标识一个特定类的序列化版本。当一个类被序列化时,serialVersionUID的值会被写入序列化数据中。
如果我们没有显式定义这个变量,Java虚拟机会根据类的属性计算出一个唯一的值,并在序列化时将该值赋给serialVersionUID,随类一起进行序列化。
当反序列化时,Java会使用序列化数据中的serialVersionUID与当前类的serialVersionUID(一般序列化的场景是传输,A端传到B端,A和B都有这个类)进行比较,以确定是否可以成功反序列化。
在Java中,如果一个类没有显式地定义serialVersionUID,Java会根据类的结构自动生成一个默认的serialVersionUID。然而,当类的结构发生变化时(例如添加或删除字段、修改方法等),默认的serialVersionUID可能会发生变化,这可能会导致反序列化失败(比如A端类结构变化,这个类的serialVersionUID也会发生变化,但B端类没有变化,serialVersionUID没有变化,两者对比不相等,反序列化失败)。
为了避免这种情况,可以在类中显式地定义一个私有的static final long serialVersionUID字段,并赋予它一个固定的值。一旦手动定义了该常量,Java虚拟机就不会再进行计算。
这样,无论类的结构如何变化,serialVersionUID都会保持不变,从而确保反序列化的兼容性。
private static final long serialVersionUID = 1L
因此,private static final long serialVersionUID = 1L(这个数值可以任意数值,但需要显式地声明)这句话的作用是定义一个固定的序列化版本号,以确保类的序列化和反序列化的兼容性。
A
package org.example;
import java.io.Serializable;
public class Serial implements Serializable {
private static final long serialVersionUID = 6977402643848374753L;
private final int id;
private final String name;
public Serial(int id, String name) {
this.id = id;
this.name = name;
}
public String toString() {
return "DATA: " + id + " " + name;
}
}
package org.example;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class SerializeTest {
public static void main(String[] args) {
final Serial serial1 = new Serial(1, "song");
System.out.println("Object Serialize" + serial1);
try {
FileOutputStream fileOutputStream = new FileOutputStream("serialTest.txt");
ObjectOutputStream oos = new ObjectOutputStream(fileOutputStream);
oos.writeObject(serial1);
oos.flush();
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
B
package org.example;
import java.io.Serializable;
public class Serial implements Serializable {
private static final long serialVersionUID = 6977402643848374753L;
private final int id;
private final String name;
public Serial(int id, String name) {
this.id = id;
this.name = name;
}
public String toString() {
return "DATA: " + id + " " + name;
}
}
package org.example;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class DeserializeTest {
public static void main(String[] args) {
Serial serial2;
try {
FileInputStream fileInputStream = new FileInputStream("serialTest.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
serial2 = (Serial) objectInputStream.readObject();
objectInputStream.close();
System.out.println("Object Deserialize" + serial2);
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
}
}