作用
避免程序运行结束后Java对象消失,而且方便在网络上传输,也可以弥补某些平台的差异,字节序列可以在其他平台反序列成对象
序列化
- 什么是序列化:将Java对象转成字节序列,持久化保存在磁盘上
// 创建一个对象输出流,并创建输出文件
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(new File("User.text")));
// 将User对象写到文件中
outputStream.writeObject(User);
// 关流
outputStream.close;
反序列化
- 什么是反序列化:将字节序列转换成Java对象
// 读取文件创建对象输入流
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(new File("User.txt")));
// 将输入流转换成Java对象
User user = (User) inputStream.readObject();
inputStream.close();
实体类
- 需要进行序列化和反序列化的实体类必须实现Serializable接口,否则会抛出异常。如果没有显示的声明serialVersionUID,编译器会自动生成一个,在反序列化的时候比较,相同才可以反序列化成功。
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String userName;
private String passWord;
private String age;
private String phoneNumber;
public User() {
System.out.println("构造方法");
}
}
Serializable接口作用
- 一个可序列化的标识,查看源码会发现是一个空接口,真的序列化不需要他完成,类实现类这个接口标名这个类可以序列化和反序列化。
- 被static修饰的字段不会序列化(序列化是对象的状态,不是类的),被transient修饰的字段也不会被修饰(如果不想被序列化的字段可以用这个字段修饰)。
serialVersionUID是什么
- 序列化前后的唯一标识,序列化后的serialVersionUID和实体类中的serialVersionUID是什么两者保持一直才会反序列化成功。如果你没有显示的声明serialVersionUID,编译器会自动生成,实体类的改变对应serialVersionUID改变(如果显示的声明了 类改变序列Id也不会改变)。
加强控制序列化和反序列化
- 实体类需要实现Externalizable接口,Externalizable接口继承了Serializable接口,加了两个方法writeExternal()、readExternal()会在序列化前后自动调用,可以重写这两个方法添加在实例化前后的额外操作来实现对序列化和反序列化的加强控制。
public class User implements Externalizable {
private String id;
private String userName;
private String passWord;
private String age;
private String phoneNumber;
public User() {
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
if (password == null) {
throw new IllegalArgumentException("账号不能为空! 反序列化失败");
}
}
}
tips
- 序列化和反序列化不会调用类的构造方法