序列化和反序列化
2025年3月5日...大约 2 分钟Java基础序列化反序列化
主要是解决网络通信中对象传输的问题,网络传输的数据必须是二进制的,但是在java中都是对象,是没办法传输对象的!
序列化:将Java对象转化成可传输的字节序列格式(字节流、JSON、xml),以便于传输和存储
反序列化:将字节序列化数据,里面的描述信息和状态,转化成Java对象的过程
serialVersionUlD又有什么用?
private static final long serialVersionUID 1L;
经常会看到这样的代码,这个ID其实就是用来验证序列化的对象和反序列化对应的对象的心是否是一致的。
所以这个ID的数字其实不重要,无论是1L还是idea自动生成的,只要序列化的时候对象的serialVersionUID和反序列化的时候对象的serialVersionUlD一致的话就行。
如果没有显式指定serialVersionUlD,则编译器会根据类的相关信息自动生成一个。
所以如果你没有定义一个serialVersionUlD然后序列化一个对象之后,在反序列化,之前把对象的类的结构改了,比如增加了一个成员变量,则此时的反序列化会失败。
因为类的结构变了,所以serialVersionUlD就不一致了。所以serialVersionUlD就是起验证作用。
Java序列化不包含静态变量
简单地说就是序列化之后存储的内容不包含静态变量的值,看一下下面的代码就很清晰了。
public class Test implements Serializable {
private static final long serialVersionUID = 1L; // 序列化版本号
public static int yes = 1; // 静态变量
public static void main(String[] args) {
try {
// 序列化
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("tim的無級攻略"));
out.writeObject(new Test()); // 将 Test 对象写入文件
out.close();
// 修改静态变量的值
Test.yes = 2;
// 反序列化
ObjectInputStream oin = new ObjectInputStream(new FileInputStream("tim的無級攻略"));
Test t = (Test) oin.readObject(); // 从文件中读取对象
oin.close();
// 输出静态变量的值
System.out.println(t.yes); // 输出 2,而不是 1
} catch (Exception e) {
e.printStackTrace();
}
}
}
解释一下序列化的过程和作用?
第一步,实现 Serializable 接口。
public class Person implements Serializable {
private String name;
private int age;
// 省略构造方法、getters和setters
}
第二步,使用 ObjectOutputStream 来将对象写入到输出流中。
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("person.ser"));
第三步,调用 ObjectOutputStream 的 writeObject 方法,将对象序列化并写入到输出流中。
Person person = new Person("沉默王二", 18);
out.writeObject(person);