序列化流和反序列化流(ObjectOutputStream/ObjectInputStream)
序列化流:ObjectOutputStream
反序列化流:ObjectInputStream
概述:
ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。可以使用 ObjectInputStream 读取(重构)对象。通过在流中使用文件可以实现对象的持久存储。就是讲对象存储到文本文件中。
实现序列化:
1. 类通过实现 java.io.Serializable 接口以启用其序列化功能。
2. 未实现此接口的类将无法使用其任何状态序列化或反序列化,该接口没有任何方法,是一个标记接口。
3. 未实现序列化抛出为序列化异常:NotSerializableException。
4. 序列化数据后,再次修改类文件,读取数据会出现问题,使用 transient 关键字声明不需要序列化的成员变量。
序列化和反序列化代码演示:
输出结果为:小红 | 20
package day0506;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class demo13 {
public static void main(String[] args) throws FileNotFoundException,
IOException, ClassNotFoundException {
Write();
Read();//输出结果为:小红|20
}
//创建读的方法(返序列化)
public static void Read() throws FileNotFoundException, IOException, ClassNotFoundException {
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("oos.txt"));
Object readObject = ois.readObject();
if (readObject instanceof Person) {
Person p=(Person) readObject;
System.out.println(p.getName()+"|"+p.getAge());
}
}
//创建写的方法(序列化)
public static void Write() throws FileNotFoundException, IOException {
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("oos.txt"));
oos.writeObject(new Person("小红", 20));
oos.close();
}
}
//创建人类
class Person implements Serializable{
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "person [name=" + name + ", age=" + 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;
}
}
使用 transient 关键字声明不需要序列化的成员变量。
输出结果为:小红 | 0
package day0506;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class demo13 {
public static void main(String[] args) throws FileNotFoundException,
IOException, ClassNotFoundException {
Write();
Read();//输出结果为:小红|0
}
//创建读的方法(返序列化)
public static void Read() throws FileNotFoundException, IOException, ClassNotFoundException {
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("oos.txt"));
Object readObject = ois.readObject();
if (readObject instanceof Person) {
Person p=(Person) readObject;
System.out.println(p.getName()+"|"+p.getAge());
}
}
//创建写的方法(序列化)
public static void Write() throws FileNotFoundException, IOException {
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("oos.txt"));
oos.writeObject(new Person("小红", 20));
oos.close();
}
}
//创建人类
class Person implements Serializable{
private String name;
private transient int age;//防止成员变量序列化
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "person [name=" + name + ", age=" + 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;
}
}
异常名称: java.io.InvalidClassException
异常字符串:
day0506.Person; local class incompatible:
stream classdesc serialVersionUID = 8127820720723137671,
local class serialVersionUID = -5481014064123845604
类在已经被保存到本地的文本文件中,如果修改了类,再次读取(反序列化)会出现序列化 Id 不配。
解决办法:
添加静态序列号
class Person implements Serializable{
/**
* 添加固定的序列号,及时随便修改,也是读取之前写入的类,不会报错。
*/
private static final long serialVersionUID = -4883211314949864878L;
String name;
private transient int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "person [name=" + name + ", age=" + 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;
}
}