Java IO:可序列化

时间:2020-01-09 10:36:07  来源:igfitidea点击:

JavaSerializable接口(java.io.Serializable是类要进行序列化和反序列化时必须实现的标记接口。Java对象序列化(写入)是通过ObjectOutputStream完成的,而反序列化(读取)是通过完成的。 ObjectInputStream。

" Serializable"是标记接口,表示它不包含任何方法。因此,实现" Serializable"的类不必实现任何特定的方法。因此,实现" Serializable"只会告诉Java序列化类该类旨在用于对象序列化。

可序列化的示例

这是一个实现JavaSerializable接口的类的示例:

import java.io.Serializable;

public static class Person implements Serializable {
    public String name = null;
    public int    age  =   0;
}

如我们所见," Person"类实现了" Serializable"接口,但实际上并未实现任何方法。如前所述,Java的" Serializable"接口只是一个标记接口,因此没有实现方法。

要查看序列化和反序列化实现" Serializable"的对象的完整示例,请参见我的ObjectInputStream教程。

serialVersionUID

除了实现" Serializable"接口之外,用于序列化的类还应该包含一个名为" serialVersionUID"的" private static final long"变量。

这是之前的Person类,并添加了serialVersionUID变量:

import java.io.Serializable;

public static class Person implements Serializable {

    private static final long serialVersionUID = 1234L;

    public String name = null;
    public int    age  =   0;
}

Java的对象序列化API使用serialVersionUID变量来确定反序列化的对象是否已使用该类的相同版本进行序列化(写入),因为它现在正尝试对其进行反序列化。

想象一个" Person"对象被序列化到磁盘上。然后对Person类进行更改。然后,我们尝试反序列化存储的Person对象。现在,序列化的" Person"对象可能不对应于" Person"类的新版本。

为了检测到此类问题,实现" Serializable"的类应包含" serialVersionUID"字段。如果我们对该类进行了较大的更改,则还应该更改其" serialVersionUID"值。

Java SDK和许多Java IDE都包含生成serialVersionUID的工具,因此我们不必这样做。

今天的对象序列化

在当今世界(2014年及以后)中,许多Java项目使用与Java序列化机制不同的机制来序列化Java对象。例如,Java对象被序列化为JSON,BSON或者其他更优化的二进制格式。这具有对象也可以被非Java应用程序读取的优点。例如,在Web浏览器中运行的JavaScript可以在本地对JSON进行序列化和反序列化。

顺便说一下,这些其他对象序列化机制通常不需要Java类实现" Serializable"。他们通常使用Java Reflection检查类,因此实现" Serializable"接口将是多余的,因为它不会添加任何有用的信息。

有关序列化的更多信息

对象序列化本身就是一个主题。该Java IO教程主要侧重于流和读取器/写入器。因此,在这一点上,我将不深入讨论对象序列化。另外,已经有很多关于Java对象序列化的在线文章。我不再重复,而是给我们提供了对该主题的更深入说明的链接。