1.Serializable接口
- implements Serializable*只是为了标注该对象是可被序列化的。
序列化是将对象的状态信息(也就是实例变量) → 可以存储或传输的格式 的过程。 - 反序列化是通过从存储或者网络读取对象的状态 → 重新创建该对象。
当创建一个类并实现Serializable之后,在你的类名上:Alt+Enter,intellij IDEA就会提示自动创建serialVersionUID。
private static final long serialVersionUID = 924539758954684144L;
Java提供的Serializable接口是一个空接口;如果一个类实现了Serializable接口,
该接口给类添加了serialVersionUID,假设类A 序列号为12L 产生了一个对象a,a被写入了磁盘当中,这时候,类A被修改,当被修改
* 之后,类A的序列号也会对应发生改变
* 该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。
* 如果接收者加载的该对象的类的 serialVersionUID 与对应的发送者的类的版本号不同,
* 则反序列化将会导致 InvalidClassException。可序列化类可以通过声明名为 "serialVersionUID" 的字段(该字段必须是静态 (static)、最终 (final) 的 long 型字段)
* 显式声明其自己的 serialVersionUID:
1、那么就代表这个类以及其子类是自动支持序列化和反序列化的,
2、序列化时,只对对象的状态进行保存,而不管对象的方法。如果一个类没有实现Serializable接口,那么默认是不能被序列化的,除非使用其他办法。
3、如果一个类实现了Serializable接口,其父类没有实现Serializable接口,那么父类必须有无参的构造器,并且父类中的状态默认不能被序列化。
4、序列化的实例变量引用其他对象,则引用对象也会被序列化;
5、并非所有的对象都可以序列化。
在什么情况下需要使用到Serializable接口呢??
1、当想把的内存中的对象状态保存到一个文件中或者数据库中时候;
2、当想用套接字在网络上传送对象的时候;
3、当想通过RMI传输对象的时候;
例如:
(实现Serializable接口,反序列化得到的对象的创建是深拷贝)
(实现Cloneable接口实现的是对象的浅拷贝)
// 序列化接口, 没有任何抽象方法,仅仅起到标记作用,告诉虚拟机它可以序列化
import java.io.Serializable;
public class Student implements Serializable{
// 要求对象中的所有属性也都是可以序列化
private int id;
private String name;
private Address address; // 临时的,瞬时的transient
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package day17;
import java.io.*;
public class TestStudent {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Student student = new Student();
student.setId(1);
student.setName("张三");
Address addr = new Address();
addr.setName("北京市海淀区xx街道");
student.setAddress(addr);
// 序列化就是将对象变为输出字节流
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("d:\\student.obj"));
os.writeObject(student);
os.writeInt(10);
os.writeObject(null);
os.close();
// 反序列化
ObjectInputStream is = new ObjectInputStream(new FileInputStream("d:\\student.obj"));
Student s = (Student)is.readObject();
System.out.println(s.getId());
System.out.println(s.getName());
System.out.println(s.getAddress());
System.out.println(is.readInt());
if(is.readObject()== null){
System.out.println("结束了");
}
is.close();
System.out.println(student == s);
}
}