[java IO流]之 序列化流和反序列化流(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;

  }

}
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!