为什么要使用Serializalbe
Serializable
public interface Serializable {
}
实体类实现Serializable后可以将实体类序列化进行传输。
import java.io.Serializable;
/**
* @author Zzwen
* @date 2020-9-1 15:10
*/
public class SerializationA implements Serializable{
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "SerializationA{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
主要作用在网络上传送对象的字节序列,把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中。如分布式系统中,共用统一实体类,实体对象将会在不同服务中传输,就必须将实体对象进行序列化后传输。
简单的例子,将对象序列化存入文本文件中,再从文本中读取数据反序列化成对象。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* 序列化测试
*
* @author Zzwen
* @date 2020-9-1 15:07
*/
public class MainApplication {
private static final String PATH = "D:\\IDEA-U\\workplace\\test\\serialization.txt";
public static void main(String[] args) throws IOException, ClassNotFoundException {
SerializationA a = new SerializationA();
a.setName("zhang san");
a.setAge(25);
System.out.println(a);
serialization(a);
SerializationA deserialization = deserialization();
System.out.println(deserialization);
}
public static void serialization(SerializationA a) throws IOException {
File file = new File(PATH);
FileOutputStream outputStream = new FileOutputStream(file);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(a);
objectOutputStream.close();
}
public static SerializationA deserialization() throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File(PATH)));
SerializationA serializationA = (SerializationA) ois.readObject();
System.out.println("反序列化成功");
return serializationA;
}
}
对于每个可序列化对象在序列化之后都会生成一个序列化id用于校验序列化对象在序列化和反序列化前后是否版本一致。
private static final long serialVersionUID;
简单的例子
例如:
首先,将对象序列化存入文本中。修改对象实体类属性定义后再从文本读取进行反序列化,这时将会产生反序列化报错。
//修改SerializationA类属性定义,这里多添加了一个add属性变量
import java.io.Serializable;
/**
* @author Zzwen
* @date 2020-9-1 15:10
*/
public class SerializationA implements Serializable{
private String name;
private Integer age;
private String add;
public String getAdd() {
return add;
}
public void setAdd(String add) {
this.add = add;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "SerializationA{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
修改后进行反序列化,报错如下:
Exception in thread "main" java.io.InvalidClassException: com.example.serilization.entity.SerializationA;
local class incompatible: stream classdesc serialVersionUID = 9022149661973760893,
local class serialVersionUID = -6546254142708022176
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:699)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1885)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1751)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2042)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
at com.example.serilization.MainApplication.deserialization(MainApplication.java:42)
at com.example.serilization.MainApplication.main(MainApplication.java:28)
出错的原因就是因为前后的serialVersionUID不一致。
若想要解决这个问题,只需要在序列化对象中添加serialVersionUID 即可。
private static final long serialVersionUID = 1L;
参考资料:
010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101