Java序列化与反序列化详解

serialVersionUID 的作用

标识类版本: serialVersionUID 是用于识别类版本的唯一标识符。

将一个对象序列化时,JVM 会将对象所属类的 serialVersionUID 写入序列化后的字节流中。

在反序列化时,JVM 会检查字节流中的 serialVersionUID 是否与当前加载的类的 serialVersionUID 匹配。

如果匹配,反序列化成功;如果不匹配,就会抛出 InvalidClassException

serialVersionUID 可以是任意的 long 型数字,如 1L123456789L

当类的变化会破坏现有数据的兼容性(如删除关键字段、改变类的继承结构等),则更新 serialVersionUID

类:

1
2
3
4
5
6
7
8
9
10
import java.io.Serializable;

public class HackInfo implements Serializable {
private static final long serialVersionUID = 1L;
//明确指定一个 serialVersionUID,并在类修改后保持其不变,以确保类的不同版本在序列化和反序列化时兼容。
public String id;
public String name;

public String newArgs;
}

序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class SerializeDemo {
public static void main(String[] args) throws IOException {
HackInfo hack=new HackInfo();
hack.id="hid";
hack.name="hname";

FileOutputStream fos=new FileOutputStream("E:\\Java\\JWeb\\data\\test.txt");

ObjectOutputStream out=new ObjectOutputStream(fos);

out.writeObject(hack);
out.close();
fos.close();
System.out.println("Success");
}
}

反序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.io.*;

public class DeserializeDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
HackInfo hack=null;//HackInfo hack = null; 仅声明了变量但未创建对象,而 HackInfo hack = new HackInfo(); 则声明了变量并创建了一个新的 HackInfo 对象。
FileInputStream fis=new FileInputStream("E:\\Java\\JWeb\\data\\test.txt");
ObjectInputStream dis=new ObjectInputStream(fis);
hack=(HackInfo)dis.readObject();
dis.close();
fis.close();
System.out.println(hack);
System.out.println("Name:"+hack.name);
System.out.println("Id:"+hack.id);
System.out.println("GoodBye");

}
}