目录
1:什么是序列化和反序列化
序列化简单来说就保存对象在内存中的状态,比如变量的值。这是Java提供的用来保存 Object state,一种保存对象状态的机制,用来传输对象(网路传输、或者本地的硬盘传输保存)。只有实现了serializable接口的类的对象才能被实例化。serializable接口就是Java提供用来进行高效率的异地共享实例对象的机制,实现这个接口即可。
序列化:把对象转换为字节序列的过程叫做对象的序列化,用于传输对象
反序列化:把字节序列恢复成对象的过程叫做对象的反序列化,用于回复对象,在反序列化时,Java虚拟机会使用对象中的默认构造函数来创建对象实例,然后通过反射
2:序列化的作用
1:将把对象永久的保存在磁盘文件上,需要的时候从硬盘读取文件变成对象
比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。
2:网络传输对象(RPC远程调用)
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。
3:当你想用套接字在网络上传输对象时
serializable接口就是Java提供用来进行高效率的异地共享实例对象的机制,实现这个接口即可。
3:序列化实现
3.1:序列化实现要素
1:实现Serializable接口,给出serialVersionUID的值(1L便于通用版本使用,随机值便于不同版本使用)
2:使用ObjectOutputStream的writeObject方法实现类到字节流的序列化操作
3:使用ObjectInputStream的readObject方法实现类字节流到类的反序列化操作
4:static和transient修饰的属性字段无法序列化
3.2:代码验证
第一步新建一个实体类:
package com.thit.serializable;
import java.io.Serializable;
//如果不实现Serializable接口,序列化会报错
public class Persion implements Serializable{
//序列化ID(serialVersionUID)如果不一样,会导致反序列话失败,报错
//Java提供两种机制
//1:固定值1L,不同版本都能适配
//2:随机值2089065545470651615L,便于版本控制,不同版本对应不同的值
private static final long serialVersionUID = 1L;
//private static final long serialVersionUID = 2089065545470651615L;
private int id;
public static int age=0;//静态方法无法序列化
private transient String address;//transient(瞬态关键字)阻止该字段序列化
private String name;
//省略get、set方法
}
测试方法分为序列化合反序列化
package com.thit.serializable;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class Serializable1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//序列化方法
SerializableTest();
System.out.println("-----序列化完成-----");
//反序列化方法
FanSerializableTest();
}
private static Persion FanSerializableTest() {
// TODO Auto-generated method stub
try {
//解析本地文件
InputStream inputStream=new FileInputStream("G:\\io\\序列化\\1\\1.txt");
ObjectInputStream objectInputStream=new ObjectInputStream(inputStream);
ArrayList<Persion> list= (ArrayList<Persion>) objectInputStream.readObject();
//该persion1跟
Persion persion=null;
System.out.println("反序列化产长度:"+list.size());
persion=list.get(0);
System.out.println("年龄:"+persion.age);
System.out.println(persion);
persion=list.get(1);
System.out.println(persion);
System.out.println("年龄:"+persion.age);
persion.age= 20;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
static void SerializableTest(){
Persion persion=new Persion();
persion.setId(1);
persion.setName("张三");
persion.setAddress("北京");
Persion persion1=new Persion();
persion1.setId(2);
persion1.setName("李四");
persion1.setAddress("郑州");
ArrayList<Persion> list=new ArrayList<>();
list.add(persion1);
list.add(persion);
try {
//将类序列化到本地文件,便于测试
OutputStream stream=new FileOutputStream("G:\\io\\序列化\\1\\1.txt");
ObjectOutputStream objectOutputStream=new ObjectOutputStream(stream);
objectOutputStream.writeObject(list);
objectOutputStream.flush();
persion.age=22;
persion1.age=23;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
测试结果如下: