对象中的数据,以流的形式,写入到文件中保存
过程称为写出对象,对象的序列化
ObjectOutputStream将对象写到文件中,实现序列化
在文件中,以流的形式,将对象读取出来,
读取对象,对象的反序列化
ObjectInputStream将文件对象读取出来,实现反序列化
示例:
简单写一个类:
package demo; import java.io.Serializable; public class Person implements Serializable { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } public Person(String name, int age) { super(); this.name = name; this.age = age; } public Person() { } }
测试:
package demo; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class ObjectStreamDemo { public static void main(String[] args) throws IOException, ClassNotFoundException { function1();// 写入 function2();// 读取 } public static void function1() throws IOException { FileOutputStream fos1 = new FileOutputStream("d:\\person.txt"); ObjectOutputStream oos1 = new ObjectOutputStream(fos1); Person p1 = new Person("zhangsan", 18); oos1.writeObject(p1); oos1.close(); } public static void function2() throws IOException, ClassNotFoundException { FileInputStream fis1 = new FileInputStream("d:\\person.txt"); ObjectInputStream ois1 = new ObjectInputStream(fis1); Object object = ois1.readObject(); System.out.println(object); ois1.close(); } }
注意事项:
1.静态不能序列化,如果将Person类的age加上static,然后序列化操作,发现无论怎样,总有age=0
原因:对象序列化,而静态不属于对象,属于类,对象不包含静态,所以静态不能序列化,age=0的原因是默认为0
transient关键字:阻止成员变量序列化
有时候不希望成员变量序列化,但又不能将它定义为静态,这时候加上transient关键字即可
再解释下上边的person类是serializable接口的实现类:
这个接口中没有方法,称为标记性接口,起到标记作用,如果person类被标记才可以被序列化
序列号冲突问题:
原理通俗解释:
定义了一个person类,定义了两个私有成员变量,编译生成新文件person.class文件
编译器根据类的定义,会给class文件计算出一个序列号,这时候将class文件写入某个文件
读取的时候会对比序列号,序列号相同则反序列成功
如果突然修改person类的源码,这时候新编译后的class文件和之前的序列号不同,
然而文件中保存的是之前的序列号,这时候对比序列号,不一致,所以会抛出异常
解决序列号冲突问题的办法:
在自定义类中自定义序列号:
加入这一行,前部分不可改,后边的数字可以随意改
//固定写法 private static final long serialVersionUID = 42L;