本片文章我们讲一讲Java自带的序列化方式:通过Serializable接口完成对象的序列化与反序列化。
我们构造一个雇员对象Employee,该对象属于某一部门Department,拥有多个角色权限Role。对于该类的定义来说,需要实现Serializable接口;如果需要非基础类型成员属性能够被序列化的话,该成员变量所属的类也应该实现Serializable接口。Pojo类定义如下所示:
Employee:
public class Department implements Serializable {
private final static long serialVersionUID = 123L;
//部门名称
private String name;
//简介
private transient String desc;
public Department(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
@Override
public String toString() {
return "Department{" +
"name = '" + name + '\'' +
", desc = '" + desc + '\'' +
'}';
}
}
Department:
public class Department implements Serializable {
private final static long serialVersionUID = 123L;
//部门名称
private String name;
//简介
private transient String desc;
public Department(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
@Override
public String toString() {
return "Department{" +
"name = '" + name + '\'' +
", desc = '" + desc + '\'' +
'}';
}
}
Role:
public class Role implements Serializable {
private final static long serialVersionUID = 123L;
//角色名称
private String name;
//描述
private transient String desc;
public Role(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
@Override
public String toString() {
return "Role{" +
"name = '" + name + '\'' +
", desc = '" + desc + '\'' +
'}';
}
}
这三个 Pojo类中都显示定义了serialVersionUID属性,这个代表了该类的序列化id,如果序列化id不一致的话无法被序列化。默认情况下,不进行定义的话,会有一个隐式定义 为1L的值。
对于这三个Pojo类的desc属性,我都使用了transient关键字进行修饰,用来表示该属性并不会被序列化。
运行代码:
public class Main {
public static void main(String[] args) throws Exception {
Employee employee = Enums.EmployeeEnum.ZHANGSAN.getEmployee();
System.out.println("\033[1;33m序列化之前的Group\033[0m:" + employee + "\n\n");
//用来指向序列化的对象的二进制数组
byte[] bytes;
//用来指向反序列化后生成的对象
Employee employee1;
//a.Java的Serializable接口序列化
/**
* 1.将对象输出流转为其他形式的输出流,这里我转为了二进制数组输出流
* 也可以转换为其他形式的输出流,比如
* FileOutputStream fos = new FileOutputStream("E:\\xx.xx");
* ObjectOutputStream oos = new ObjectOutputStream(fos);
* 输出生成了xx.xx二进制文件
*/
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
/**
* 2.通过 ObjectOutputStream::writeObject 方法将对象序列化至输出流
*/
oos.writeObject(employee);
/**
* 3.获取输出流中二进制数组的拷贝
*/
bytes = bos.toByteArray();
System.out.println("\033[1;33m[Java的Serializable接口序列化]得到的byte数组的长度:\033[0m" + bytes.length);
/**
* 4.将数据重新输入对象输入流
*/
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
/**
* 5.通过 ObjectInputStream::
*/
employee1 = (Employee) ois.readObject();
System.out.println("\033[1;33m[Java的Serializable接口序列化]得到的Employee对象:\033[0m" + employee1);
}
}
结果如下:
本次实验代码:代码地址,欢迎访问v!