为什么要使用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;

参考资料:

posted @ 2020-09-01 20:43  Z、悟空  阅读(156)  评论(0编辑  收藏  举报