1.对象序列化和反序列化
序列化:就是将内存模型变为字节字符,写入IO流中,方便传输;
反序列化:从IO流中恢复成为对象模型;
2.使用ObjectOutputStream/InObjectStream
package com.ydlclass.com.ydlclass.serializable;
import java.io.Serializable;
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private int age;
private transient String sex;//不需要序列化字段
public User(int age, String sex) {
this.age = age;
this.sex = sex;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public User() {
}
public User(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"age=" + age +
", sex='" + sex + '\'' +
'}';
}
}
package com.ydlclass.com.ydlclass.serializable;
import org.junit.Test;
import java.io.*;
public class SerializableTest {
@Test
public void testUser() throws IOException {
//将对象输出到磁盘上
//对象输出流需要一个文件输出流输出,所以需要一个文件输出流对象
OutputStream outputStream = new FileOutputStream("E:\\Product.log");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
//输出对象到文件中
objectOutputStream.writeObject(new User(12,"男"));
//关闭流文件
objectOutputStream.close();
outputStream.close();
//直接运行抛出异常:对象无法序列化
}
@Test
//反序列化
public void testUser2() throws IOException, ClassNotFoundException {
InputStream inputStream = new FileInputStream("E:\\Product.log");
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
//将对象转化为一个对象;
Object o = objectInputStream.readObject();
System.out.println(o);//重写toString方法;
objectInputStream.close();
inputStream.close();
}
}
3.序列化版本号:
工程容易变更,加上jdk版本不一致,就有可能导致序列化的逻辑不一致;
手动的给需要序列化版本的类文件加上一个serializableId;
4.Note:
所有需要网络传输的对象都需要实现serializable接口;
使用transient关键字,可以制定不序列化某个字段;
序列化对象的引用成员变量也必须是可序列化的,否则对象序列化失败;
反序列化时必须有对象的class文件;(不同的工程对别的工程序列化的对象时会抛出错误)
当通过文件、网络读取序列化的对象,必须按照写入的顺序读取;
单例类的序列化,需要重写readResovle方法,否则会破坏单例原则;
所有需要实现序列化的类都加上序列化版本的ID;
5.idea中提供了自动化生成序列化版本号id的快捷键(手动开启)