序列化的定义
序列化:把对象转化为可传输的字节序列过程称为序列化。
反序列化:把字节序列还原为对象的过程称为反序列化。
为什么要序列化?
当两个进程进行网络传输时,需要发送各种类型的数据,如图片,文档等,而这些数据在网络中往往以二进制的形式传输,因此,在发送数据时我们需要对数据序列化将其转化为二进制序列,当接受数据时则需要将二进制序列反序列化恢复成原先的数据对象。
Java 是如何实现序列化的?
在Java中提供了ObjectlnputStream与ObjectOutputStream这两个类用于序列化对象的操作。使用对象输出流输出序列化对象(序列化)。使用对象输入流读入对象(反序列化)。进行序列化,反序列化的对象必须实现Serializable接口,Serializable接口中没有定义任何方法,仅仅被用作一种标记,以被编译器作特殊处理。
将
public class Student implements Serializable{
//年龄
private int age;
//名字
private String name ;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
把Student对象设置值后写入文件
FileOutputStream fos = new FileOutputStream("D:\JavaFileTest\HomeWork2\students.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
Student stu=new Student();
stu.setAge(18);
stu.setName("LiHua");
oos.writeObject(stu);
oos.flush();
oos.close();
再从文件读取出来转换为对象
FileInputStream fis = new FileInputStream("D:\JavaFileTest\HomeWork2\students.txt");
ObjectInputStream oin = new ObjectInputStream(fis);
Student stu=(Student) oin.readObject();
System.out.println("name="+stu.getName()+"age"+stu.age);
以上把Student对象进行二进制的数据存储后,并从文件中读取数据出来转成Student对象就是一个序列化和反序列化的过程。
JAVA序列化中常见的问题
transient关键字
transient修饰的属性,不可以被序列化
static 属性不能被序列化
序列化保存的是对象的状态,静态变量属于类的状态,因此 序列化并不保存静态变量。
被序列化的类的内部的所有属性,必须是可序列化的
serialVersionUID 常量
在对象进行序列化或反序列化操作的时候,如果序列化的 JDK 版本和反序列化的 JDK 版本不统一,则可能造成异常。因此在序列化操作中引入了一个serialVersionUID 的常量来验证版本的一致性。在进行反序列化时,JVM 会把传来的字节流中的 serialVersionUID 与本地相应实体(类)的serialVersionUID 进行比较。如果相同就可以进行反序列化,否则就会出现异常。