Java 序列化的一些理解
序列化的目的: 持久化保存对象或复用对象, 正常来说对象只存在于jvm(或内存)中, 如果想在jvm停止运行后保存对象的状态, 或通过网络复用对象(RMI), 则必须序列化.
示例:
1 import java.io.Serializable; 2 3 public class Person implements Serializable { 4 private static final long serialVersionUID = 1L; 5 6 private static int age = 10; //类变量不会被序列化 7 private String name; 8 9 public Person(String name) { 10 this.name = name; 11 } 12 13 public String getName() { 14 return this.name; 15 } 16 }
测试类:
1 import java.io.File; 2 import java.io.FileInputStream; 3 import java.io.FileOutputStream; 4 import java.io.ObjectInputStream; 5 import java.io.ObjectOutputStream; 6 7 public class Test { 8 public static void main(String[] args) throws Exception { 9 File file = new File("person.ser"); 10 FileOutputStream fos = new FileOutputStream(file); 11 ObjectOutputStream oos = new ObjectOutputStream(fos); 12 13 Person person = new Person("John"); 14 oos.writeObject(person); 15 oos.close(); 16 //下边为反序列化 17 System.out.println(file.getAbsolutePath()); 18 FileInputStream fis = new FileInputStream(file); 19 ObjectInputStream ois = new ObjectInputStream(fis); 20 21 Person newOne = (Person) ois.readObject(); 22 System.out.println("get person: " + newOne.getName()); 23 ois.close(); 24 } 25 }
这样就把person对象以"person.ser"保存到了磁盘上, 打开该文件会看的属性值"John"
serialVersionUID的一些知识
当反序列化是需要读取到的对象进行转型
Person newOne = (Person) ois.readObject();
此时Person类对应的是反序列化是jvm里的类, 为保证读取到的对象能正确的转型, 需要将读取到的对象的serialVersionUID和此时jvm里Person类的serialVersionUID进行对比,
如果一致则说明可以正常转型, 如果不一致则说明反序列化得到的对象所属的类与当前jvm里的类版本不一致, 可能会导致转型错误.
但是如果serialVersionUID一致, 但是jvm里的Person类和反序列化得到对象所属的类确实不一样, 比如jvm里的类比反序列化得到的类多了一个成员变量, 此时也不会报错, 但该
成员变量不会被操作. 所以, 当任何一方对类做了改动都要更新serialVersionUID, 因此最好不要使用默认的值(1L), 而是使用eclipse生成的值.