22,ObjectInputStream和ObjectOutputStream
22.1对象的序列化流和反序列化流
这两个流对象是用来操作对象的。
对象的序列化:就是让对象中封装的数据可以持久化存储。
对象的反序列化:就是通过存储的文件数据获取对象实体。
对象序列化的条件:
必须要实现Serializable接口,否则无法实现对象的序列化。此接口提供了一个serialVersionUID,用于验证序列化和反序列化时是否是同一个对象,如果不是则无法反列化。
ObjectInputStream和ObjectOutputStream都是装饰类,用于增强流对象的功能。
其构造函数:
ObjectInputStream
(InputStream out)
ObjectOutputStream
(OutputStream out)
分别都接收一个字节流。
22.2对象的序列化
用到的流对象是:ObjectOutputStream
使用其方法:writerObject(被序列化的对象);
多个对象,就多次调用writerObject().
注意:对象的序列化,只存储对象中非瞬态和非静态的字段。
如:
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class ObjectOutputStream Demo {
public static void main(String[] args)throws FileNotFoundException, IOException {
//创建对象序列化流,将对象的数据保存在,指定的文件中。
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("d:\\person.object"));
//序列化对象。
oos.writeObject(new Person("李四",44));
//关闭资源
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 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;
}
}
22.3对象的反序列化
对象的反序列化使用流对象:ObjectInputStream
使用方法:readObject();此方法返回Object对象,需要进行强转。
多个对象被反序列化,就多次调用readObject()每次读取一个对象。
通过读取被序列化对象的文件,获取对象。
如:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
importjava.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
importjava.io.ObjectOutputStream;
import java.io.Serializable;
public class ObjectOutputStream Demo {
public static void main(String[] args)throws ClassNotFoundException, FileNotFoundException, IOException {
//创建对象序列化流,将对象的数据保存在,指定的文件中。
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("d:\\person.object"));
//反序列化对象。
Person p=(Person)ois.readObject();
System.out.println(p.getName()+"::"+p.getAge());
//关闭资源
ois.close();
}
}
/*
*打印结果:李四::44
*/
通过反序列化流,可以从一个存储对象数据的文件中获取这个对象,实现了对象数据的持久化存储和对象的获取。
注意:对象反序列化时要获取对象,必须要满足:
1, 有对象的序列化文件。
2, 要有对象所属的字节码文件。否则,无法获取对象。
如果一个对象被序列化后,其原有的数据被修改,这时就不能完成反序列化。
异常信息:
Exception in thread "main"java.io.InvalidClassException: IO流.Person; local class incompatible: stream classdesc serialVersionUID = -5252691168862610579, local class serialVersionUID = -7585441751578431892
这是因为serialVersionUID号不一致造成的,对象的反序列化过程中,会检查这个版本号与原对象的版本号是否一致,如果不一致就无法完成反序化,serialVersionUID在类中如果没有明确声明的情况下,会根据类中的内容默认计算出一个,当然,也可在类中自己声明一个serialVersionUID,不管类中数据是否变化,只要此号不变,就可以完成反序列化。
如:
class Person implements Serializable{//对象要序列化必须要实现此接口
private static final long serialVersionUID = 1L;//显示声明serialVersionUID
private int age;
private String name;
public Person(String name,int age) {
super();
this.name = name;
this.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;
}
}
22.4关键字 transient(瞬态)
对象的序列化,其静态和非瞬态的字段是不能被存储到文件中的。
如果一个字段不是静态,但也不想被存储到文件中,就可以加上此关键字:transient
如:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
importjava.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
importjava.io.ObjectOutputStream;
import java.io.Serializable;
public class ObjectOutputStreamDemo {
public static void main(String[] args)throws ClassNotFoundException, FileNotFoundException, IOException {
//创建对象序列化流,将对象的数据保存在,指定的文件中。
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("d:\\person.object"));
//反序列化对象
Person p=(Person)ois.readObject();
System.out.println(p.getName()+"::"+p.getAge());
//关闭资源
ois.close();
}
}
class Personimplements Serializable{//对象要序列化必须要实现此接口
private static final long serialVersionUID = 1L;//显示声明serialVersionUID
private static int age;//静态属性
private transient String name;//瞬态属性
public Person(String name,int age) {
super();
this.name = name;
this.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;
}
}
/*
*反序列化打印结果:null::0
*/
注意:多个对象的序列化,就多次调用writeObject(),多个对象的反序列化就多次调用readObject(),有几个对象就读取几个。
import java.io.FileInputStream;
import java.io.FileNotFoundException;
importjava.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
importjava.io.ObjectOutputStream;
import java.io.Serializable;
public class ObjectOutputStream Demo {
public static void main(String[] args)throws ClassNotFoundException, FileNotFoundException, IOException {
// ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("d:\\person.object"));
//序列化多个对象
// oos.writeObject(new Person("李四",33));
// oos.writeObject(new Person("张三",24));
// oos.writeObject(new Person("小强",45));
// oos.writeObject(new Person("李明",23));
// oos.close();
//创建对象序列化流,将对象的数据保存在,指定的文件中。
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("d:\\person.object"));
//反序列化多个对象。
Person p1=(Person)ois.readObject();
Person p2=(Person)ois.readObject();
Person p3=(Person)ois.readObject();
Person p4=(Person)ois.readObject();
System.out.println(p1.getName()+"::"+p1.getAge());
System.out.println(p2.getName()+"::"+p2.getAge());
System.out.println(p3.getName()+"::"+p3.getAge());
System.out.println(p4.getName()+"::"+p4.getAge());
//关闭资源
ois.close();
}
}
class Person implements Serializable{//对象要序列化必须要实现此接口
private static final long serialVersionUID = 1L;//显示声明serialVersionUID
private int age;
private String name;
public Person(String name,int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
publicvoid setName(String name) {
this.name = name;
}
publicint getAge() {
return age;
}
publicvoid setAge(int age) {
this.age = age;
}
}
/*
*打印结果:
李四::33
张三::24
小强::45
李明::23
*/
总结:对象的序列化和反序列化可以将对象持久保存,并可以随时获取对象,实现了对象中数据的持久保存。对象要序列化必须要实现Serializable接口,并声明serialVersionUID号,以免反序列化时抛出异常。对象反序列化要获取对象,首先必须有保存对象的文件,其实,必须有对象所属的字节码文件。对象中的静态字段和transient修饰的字段是不能被序列化到文件中的。
---------------------- ASP.Net+Android+IOS开发、 .Net培训、期待与您交流! ----------------------