1、序列化与反序列化是什么
序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。在IO流中,序列化就是将对象的状态写入到特定的流中的过程,如:将Java对象序列化为二进制的字节序列。
反序列化就是序列化的反过来的过程。
2、序列化和反序列化中使用到IO流的类
1)序列化IO流(ObjectOutputStream)
序列化是将对象转换为流的过程,应该对应的就是输出流,使用的是ObjectOutputStream类
链接: ObjectOutputStream帮助文档.
ObjectOutputStream的构造方法有两个一个是无参的构造方法,一个是带有OutputStream类型的参数:
ObjectOutputStream类的方法倒是挺多的,特别是带有write的方法挺多的。提供了多种写入文件中的方法,但是现在主要使用的就是带有把对象转换为二进制的字节序列的writeObject():
2)反序列化IO流(ObjectInputStream)
反序列化就是将文件中的二进制序列化转换为对象,使用的是ObjectInputStream类
链接: ObjectInputStream帮助文档.
ObjectInputStream类和ObjectOutputStream类差不多,也是只有两个构造方法,一个无参的,一个带InputStream类型参数的构造方法:
ObjectInputStream类的方法也和ObjectOutputStream类差不多,特别是带read的方法特别多,大家根据不同的情况调用就行了,这里需要注意的是readObject(),这个方法会帮我们把二进制字节序列化转换为对象:
3、对象的序列化条件
1)被用于序列化的对象必须实现Serializable 接口
2、要防止属性被反序列化,导致出现泄密的情况,可以在属性的类型前添加transient关键字,从二进制字节序列化中反序列化出来的对象获取这个属性的时候是一个null,保护了想要保护的值。
4、例子
1)创建一个个人的属性类,这个类实现Serializable 接口,并且给里面的pwd属性添加transient关键字,防止这个属性被反序列化出来
package com.company;
import java.io.Serializable;
public class Personal implements Serializable {
private String name;
private String ID;
private transient String pwd;
private int age;
private String sex;
public Personal(){}
public Personal(String name,String ID,String pwd,int age,String sex){
this.name=name;
this.ID=ID;
this.pwd=pwd;
this.age=age;
this.sex=sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getID() {
return ID;
}
public void setID(String ID) {
this.ID = ID;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
2)实例化Personal这个类并将这个对象通过ObjectOutputStream转换为二进制字节流存到“E:/zwy/zwy/01.txt”中。
分析:ObjectOutputStream的参数为OutputStream类型,所以需要使用FileOutputStream和ObjectOutputStream两个类。
package com.company;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class SerializableDemo {
public static void main(String[] args){
Personal personal=new Personal("小明","0001","123456",18,"男");
FileOutputStream fos=null;
ObjectOutputStream oos=null;
try {
fos=new FileOutputStream("E:/zwy/zwy/01.txt");
oos=new ObjectOutputStream(fos);
oos.writeObject(personal);
oos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
oos.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
二进制字节显示乱码属于正常的情况
3)从“E:/zwy/zwy/01.txt”中取出二进制字节流,并通过反序列化得到Personal对象,并打印Personal中的信息到控制台上。
分析:从文件中获取到对象使用ObjectInputStream类,ObjectInputStream类的构造参数是InputStream类型的,也要用到FileInputStream类
package com.company;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
public class DeserializableDemo {
public static void main(String[] args){
Personal personal=null;
FileInputStream fis =null;
ObjectInputStream ois=null;
try {
fis=new FileInputStream("E:/zwy/zwy/01.txt");
ois=new ObjectInputStream(fis);
personal=(Personal)ois.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally {
try {
ois.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("name:"+personal.getName());
System.out.println("ID:"+personal.getID());
System.out.println("pwd:"+personal.getPwd());
System.out.println("age:"+personal.getAge());
System.out.println("sex:"+personal.getSex());
}
}
pwd属性因为添加了transient关键字,所以反序列化出来的对象中的pwd只得到null