Java IO:可序列化
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对象序列化的在线文章。我不再重复,而是给我们提供了对该主题的更深入说明的链接。