本文共 2827 字,大约阅读时间需要 9 分钟。
顺带提一下,serialVersionUID就像是这个类的身份证一样,用于唯一标识每个类的序列化版本。
public class Dog implements Serializable {
private String name;private Integer age;@Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + '}'; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; }
}
可以看到,这个类实现了`Serializable`接口,标记它可以进行序列化操作。 如果不手动设置`serialVersionUID`,系统会自动为这个类生成一个唯一的序列化版本号。为什么需要serialVersionUID
假设我们有一个简单的Dog类,包含两个字段:`name`和`age`。当我们第一次序列化这个类时,系统会默认生成一个`serialVersionUID`,并将对象信息与这个唯一标识存储在文件中。 如果我们随后修改Dog类,增加一个新的字段`nickName`,再次进行序列化操作时,系统会检测到字段数量的变化,从而生成一个新的`serialVersionUID`。这种方法虽然可行,但存在一个问题: 当我们尝试反序列化之前的序列化文件时,系统会发现当前类的`serialVersionUID`与文件中的不一致,导致反序列化失败。 为了避免这种问题,我们可以手动设置`serialVersionUID`。例如: ```java private static final long serialVersionUID = 1L;
这样一来,无论我们对Dog类的字段进行何种修改,只要serialVersionUID
保持不变,反序列化操作就能顺利完成。
序列化代码示例:
import java.io.writeObject; import java.io.FileOutputStream; import java.io ObjectOutputStream; public class SerializeTest { public static void main(String[] args) throws IOException { ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("dogInfo.out")); Dog dog = new Dog(); dog.setName("阿福"); dog.setAge(1); objectOutputStream.writeObject(dog); objectOutputStream.flush(); objectOutputStream.close(); } }
运行上述代码后,会在指定目录生成一个名为dogInfo.out
的文件,文件内容为序列化后的Dog对象字节流。
反序列化代码示例:
import java.io.ObjectInputStream; import java.io.FileInputStream; public class DeserializeTest { public static void main(String[] args) throws IOException, ClassNotFoundException { ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("dogInfo.out")); Dog dog = (Dog) objectInputStream.readObject(); System.out.println("狗的名字:" + dog.getName()); } }
运行上述代码后,程序会读取并解析序列化文件,重新获得原来的Dog对象。
transient
修饰的字段不会被默认序列化。如果需要将这些字段包含在序列化过程中,可以手动进行处理。
转载地址:http://znwb.baihongyu.com/