一、概念:
序列化: 将对象转化为字节或字符的过程.
反序列化: 将字节或字符转化为对象的过程.
二、序列化场景:
三、序列化步骤:
- Pojo类实现Serializable接口;
- 添加序列化id(保证反序列化成功);
- 借助输入输出流进行序列化和反序列化
四、序列化中的数据安全:
在需要序列化加密的pojo对象中添加writeObject()
和readObject()
方法,在这两个方法中进行序列化加解密,对象输入输出流调用writeObject()
和readObject()
方法时自动调用这两个方法,实现了序列化的加解密.
1) 添加 private writeObject(ObjectOutpuStream out)方法,对内容进行加密再执行序列化:
private void writeObject(ObjectOutputStream out) throws Exception{
System.out.println("writeObject");
//在该方法内部自定义加密方式,如:
x = x + 2;
out.defaultWriteObject();
}
2) 添加private readObject(ObjectInputStream in)方法对内容先进行反序列化然后在执行解密操作:
private void readObject(ObjectInputStream in)throws Exception{
System.out.println("readInputStream");
in.defaultReadObject();
//在该方法内部自定义解密方式,如:
x = x - 2;
}
五、Java中序列化粒度的控制:
1) Transient :当少量属性不需要序列化时,使用此关键字修饰:
private transient int x;
private int y;
2)Externalizable:当只有少量属性需要序列化时,实现此接口然后自己进行序列化
操作,要求要序列化的对象必须手动添加无参构造方法:
class Point implements Externalizable{
private int x;
private int y;
public Point(){
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
@Override
public String toString() {
return "Point{" +
"x=" + x +
", y=" + y +
'}';
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
//手动将x,y进行序列化
out.writeInt(x);
out.writeInt(y);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
//手动按序列化时的顺序进行反序列化赋值
x = in.readInt();
y = in.readInt();
}
}
@Test
public void test04()throws Exception{
Point point = new Point();
point.setX(10);
point.setY(20);
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("a.txt"));
outputStream.writeObject(point);
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("a.txt"));
Object object = inputStream.readObject();
System.out.println(object);
}
六、Java中序列化性能的优化:
JDK自带的序列化功能会将元数据和数据一起序列化,性能较差(元数据:比如int x=4;x就是元数据),可以自己实现序列序列化或借助第三方框架只对数据进行序列化来提高性能.