为啥Java序列化要有 private static final long serialVersionUID = 1L

参考文章

在Java中,类可以实现Serializable接口以支持对象的序列化和反序列化。当一个类实现了Serializable接口时,它的对象可以被转换为字节序列,这些字节序列可以在网络上传输,或者保存到磁盘上。反之,这些字节序列也可以被反序列化为对象。

serialVersionUID是一个序列化版本号,它用于标识一个特定类的序列化版本。当一个类被序列化时,serialVersionUID的值会被写入序列化数据中。

如果我们没有显式定义这个变量,Java虚拟机会根据类的属性计算出一个唯一的值,并在序列化时将该值赋给serialVersionUID,随类一起进行序列化。

当反序列化时,Java会使用序列化数据中的serialVersionUID与当前类的serialVersionUID(一般序列化的场景是传输,A端传到B端,A和B都有这个类)进行比较,以确定是否可以成功反序列化。

在Java中,如果一个类没有显式地定义serialVersionUID,Java会根据类的结构自动生成一个默认的serialVersionUID。然而,当类的结构发生变化时(例如添加或删除字段、修改方法等),默认的serialVersionUID可能会发生变化,这可能会导致反序列化失败(比如A端类结构变化,这个类的serialVersionUID也会发生变化,但B端类没有变化,serialVersionUID没有变化,两者对比不相等,反序列化失败)。

为了避免这种情况,可以在类中显式地定义一个私有的static final long serialVersionUID字段,并赋予它一个固定的值。一旦手动定义了该常量,Java虚拟机就不会再进行计算。
这样,无论类的结构如何变化,serialVersionUID都会保持不变,从而确保反序列化的兼容性。

private static final long serialVersionUID = 1L

因此,private static final long serialVersionUID = 1L(这个数值可以任意数值,但需要显式地声明)这句话的作用是定义一个固定的序列化版本号,以确保类的序列化和反序列化的兼容性。

A

package org.example;


import java.io.Serializable;

public class Serial implements Serializable {

    private static final long serialVersionUID = 6977402643848374753L;

    private final int id;

    private final String name;

    public Serial(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public String toString() {
        return "DATA: " + id + " " + name;
    }

}

package org.example;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class SerializeTest {
    public static void main(String[] args) {
        final Serial serial1 = new Serial(1, "song");
        System.out.println("Object Serialize" + serial1);
        try {
            FileOutputStream fileOutputStream = new FileOutputStream("serialTest.txt");
            ObjectOutputStream oos = new ObjectOutputStream(fileOutputStream);
            oos.writeObject(serial1);
            oos.flush();
            oos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

B

package org.example;


import java.io.Serializable;

public class Serial implements Serializable {

    private static final long serialVersionUID = 6977402643848374753L;

    private final int id;

    private final String name;

    public Serial(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public String toString() {
        return "DATA: " + id + " " + name;
    }

}

package org.example;


import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class DeserializeTest {
    public static void main(String[] args) {
        Serial serial2;
        try {
            FileInputStream fileInputStream = new FileInputStream("serialTest.txt");
            ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
            serial2 = (Serial) objectInputStream.readObject();
            objectInputStream.close();
            System.out.println("Object Deserialize" + serial2);
        } catch (ClassNotFoundException | IOException e) {
            e.printStackTrace();
        }
    }
}


你可能感兴趣的:(实习,java,python,php)