概念
把对象以流的方式写入到文件中保存,叫做写对象,也叫做对象的序列化。
把文件中保存的对象以流的方式读取出来叫做读对象,也叫对象的反序列化。
什么时候用到序列化
当对象保存在物理介质的时候,比如对象保存到磁盘、文件
当对象在网络上传输的时候,比如通过套接字传输对象
当对象远程过程调用的时候,比如通过RMI调用对象
对象的序列化流
java.io.ObjectOutputStream extends OutputStream 用来把对象以流的方式写入到文件中保存
构造方法:
ObjectOutputStream(OutputStream out) //创建写入指定OutputStream的ObjectOutputStream
使用步骤:
1.对象类必须先实现序列化接口
2.创建ObjectOutputStream对象,构造方法中传递字节输出流
3.使用ObjectOutputStream对象中的方法wirteObject,把对象写入到文件中
4.释放资源
//如果实体类没有实现序列化接口,会抛出NotSerializableException没有序列化异常
public class Person implments Serializable{
private String name;
private int age;
//getter,setter
//tostring
//construct
}
public static void main(String[] args) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("10\\a.txt"));
oos.writeObject(new Person("monkey", 18));
oos.close();
}
对象的反序列化
java.io.ObjectInputStream extends InputStream 用来把文件中保存的对象以流的方式读取处理使用
构造方法:
ObjectInputStream(InputStream in) //创建从指定InputStream读取的ObjectInputStream
使用步骤:
前提:
实体类必须实现了Serializable接口。同时该实体类必须存在对应的class文件,否则会报ClassNotFoundException异常
1.创建ObjectInputStream对象,构造方法中传递字节输入流
2.使用ObjectInputStream对象中的方法readObject读取保存对象的文件
3.释放资源
4.使用读取处理的对象(打印)
transient关键字
static修饰的关键字优先于非静态加载到内存中(静态优先于对象进入到内存中),被static修饰的成员变量不能被序列化,因为序列化都是对象。
transient关键字意为瞬态关键字,被transient修饰的成员变量也不能序列化,当你想要起到static的作用又不想声明这个成员变量是一个静态成员变量时,就可以用transient关键字
手动设置序列号
实体类继承了Serializable接口会自动生成一个序列号,每一次类的内容改变会重写编译成class文件,重写生成序列号。
一般都手动设置序列号。原因是当class文件在序列化对象之后发生了修改,此时直接进行反序列化时就会比较这2个序列号ID,由于ID不一致会导致操作失败,抛出InvalidClassException异常。
解决的办法是无论类的定义是否经过修改,都不重新生成新的序列号,那么我们就手动设置一个序列号
实体类手动设置序列号:
public class Person implements Serializable {
private static final long serialVersionUID =1L;
private String name;
private int age;
}