序列化流和反序列化流(ObjectOutputStream/ObjectInputStream)

序列化流和反序列化流(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;

}

}

上一篇:多元统计分析及R语言建模(第五版)——第5章 广义与一般线性模型课后习题


下一篇:【java】ObjectOutputStream & ObjectInputStream 多次写入发生重复写入相同数据的问题