3

如果我们想序列化一个对象,我们可以简单地执行以下实现:

class MyClass implements Serializable
{
  private static final long serialVersionUID = 12345L;
}

并且不需要额外的努力来强制实现对象将如何写入文件和从文件中读取。Java 只负责处理所有事情。

另一方面,Externalizable确实定义了显式的序列化和反序列化方法,因此我们可以进行命令式编程。

这给我留下了一个问题:如果不需要额外的努力Serializable,让它成为我们必须实现的接口来序列化/反序列化对象的理由是什么,而不是默认情况下每个对象都可以序列化/反序列化?

4

3 回答 3

4

当程序员将一个类标记为可序列化时,他负责如果这个类将来发生变化,保存对象的程序将能够将它们读回更新的类。详细信息在 Effective Java 第 74 条:明智地实现 Serializable

还有另一个理由。你有没有注意到ObjectOutput.writeObject(Object obj)接受对象,而不是可序列化?这是因为它假定可以使用不同的序列化机制来保存对象。Serializable表示该对象应该使用 Java 标准序列化来保存

于 2015-02-24T05:24:51.733 回答
0

接口Serializable只是作为一个标识的掩码。如果每个类都有被序列化的能力,那么每个类都需要维护serialVersionUID以避免版本冲突。另外,它可能会导致安全问题:有人会使用它作为创建新对象的一种方式,尽管该对象不是由客户端代码创建的。使用 Serializable 接口是不安全的。有关更多信息,请参阅有效的 Java。

于 2015-02-24T05:31:41.273 回答
0

因为:

  1. 并非所有对象都对此具有有意义的语义。示例:单例对象
  2. 安全。如果您将对象传递给其他人的代码,并且他们始终可以捕获和传输该对象,则需要选择退出与安全相关的代码,并且当人们忽略某个对象时会出现安全漏洞。所以“默认关闭”更安全。
  3. 内置的序列化格式会为您编写的每个对象写出类名,因此效率非常低。仅将其用于数据很少的非常简单的情况。
  4. 默认序列化不会轻易地与用其他语言编写的代码共享数据,因此如果今天编写的数据将来可能需要由其他软件读取,则应考虑使用特定的表示。所以这不是一个好的长期格式。
  5. 并非所有开发人员都牢记它在所有情况下如何工作的确切规则。

如果您阅读 Joshua Bloch 的《Effective Java》一书,它会解释使用内置功能是多么棘手。大多数开发人员在很多情况下都避免使用它。这个答案给出了一个很好的经验法则https://softwareengineering.stackexchange.com/a/240432/129659

于 2015-02-24T05:43:45.073 回答