在Java中,如果一个类实现了Serializable但是抽象的,那么它应该长声明一个serialVersionUID还是子类仅要求这样做?

在这种情况下,确实确实希望所有子类都处理序列化,因为要在RMI调用中使用类型的目的。

最佳答案

提供serialVersionUID来确定反序列化对象与类的当前版本之间的兼容性。这样,在类的第一个版本中,或者在这种情况下,在抽象基类中,就没有必要。您永远不会有该抽象类的实例进行序列化/反序列化,因此它不需要serialVersionUID。

(当然,它会生成一个编译器警告,您想摆脱它,对吗?)

事实证明,詹姆斯的评论是正确的。抽象基类的serialVersionUID确实会传播到子类。鉴于此,您确实需要在基类中使用serialVersionUID。

要测试的代码:

import java.io.Serializable;

public abstract class Base implements Serializable {

    private int x = 0;
    private int y = 0;

    private static final long serialVersionUID = 1L;

    public String toString()
    {
        return "Base X: " + x + ", Base Y: " + y;
    }
}



import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class Sub extends Base {

    private int z = 0;

    private static final long serialVersionUID = 1000L;

    public String toString()
    {
        return super.toString() + ", Sub Z: " + z;
    }

    public static void main(String[] args)
    {
        Sub s1 = new Sub();
        System.out.println( s1.toString() );

        // Serialize the object and save it to a file
        try {
            FileOutputStream fout = new FileOutputStream("object.dat");
            ObjectOutputStream oos = new ObjectOutputStream(fout);
            oos.writeObject( s1 );
            oos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        Sub s2 = null;
        // Load the file and deserialize the object
        try {
            FileInputStream fin = new FileInputStream("object.dat");
            ObjectInputStream ois = new ObjectInputStream(fin);
            s2 = (Sub) ois.readObject();
            ois.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println( s2.toString() );
    }
}

在Sub中运行一次main,以使其创建并保存对象。然后在Base类中更改serialVersionUID,注释掉main中保存该对象的行(因此不再保存它,您只想加载旧的对象),然后再次运行它。这将导致异常
java.io.InvalidClassException: Base; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2

10-07 18:56
查看更多