我应该在接口上实现`serialVersionUID`吗?

时间:2017-11-25 04:51:52

标签: java serialization

在创建扩展Serializable的接口时,我应该添加serialVersionUID字段吗?

我的IDE(Netbeans 8.2)抱怨该字段丢失。但是,根据我的理解,serialVersionUID仅适用于非抽象类(将在反序列化期间实例化的特定类)。

如果需要 serialVersionUID,我该如何处理扩展接口的接口?通常,此类字段在类heirarchy中的每个类中声明。虽然这也适用于接口,但它会导致不同的IDE警告,即字段隐藏字段。

2 个答案:

答案 0 :(得分:5)

不,你不应该。在序列化或反序列化过程中,无法考虑接口的serialVersionUID。这毫无意义。 serialVersionUID适用于Serializable 类。

答案 1 :(得分:1)

对我而言,扩展Serializable的界面一开始就是一个问题,你强制实现你的界面的每个人都是Serializable他们可能不希望这样做所有。另一方面,我可以考虑这种情况有意义的情况,例如Entities(阅读@Entity)的通用界面,它必须具有ID,同时必须是Serializable

我正在努力为此找到相关文档,但我的测试显示,如果您序列化该类,并且即使,您之后也会更改接口的serialVersionUID 然后反序列化 - 它将完全反序列化的类。所以,说你有这个:

static interface ITest extends Serializable {
    public final long serialVersionUID = 123L;
}

static class TestImpl implements ITest {
    private static final long serialVersionUID = 456L;
}

首先序列化一些实例:

ObjectOutputStream oos = new ObjectOutputStream(
         new FileOutputStream(new File("/Your/Path/Here/o.ser")));
oos.writeObject(new TestImpl());

然后将接口的serialVersionUID 更改为其他值public final long serialVersionUID = 789;,编译以生成新的.class文件并对其进行反序列化:

ObjectInputStream in = new ObjectInputStream(
         new FileInputStream("/Your/Path/Here/o.ser"));
TestImpl c = (TestImpl) in.readObject();

这意味着在这种情况下,如果在界面中定义一个并不重要。

如果您想要序列化接口类本身的实例,只会重要:

Class<ITest> c = ITest.class;
// serialize c

在这种情况下,更改serialVersionUID会很重要,它会破坏序列化java.io.InvalidClassException