为什么Java需要Serializable接口?

我们大量地使用序列化,并且不得不在每个我们使用的对象上指定Serializable标签都是一种负担。 尤其是当我们不能真正改变的第三方课堂。

问题是:由于Serializable是一个空接口,并且一旦添加了implements Serializable ,Java就提供了健壮的序列implements Serializable – 为什么它们没有使所有的东西都可序列化呢?就是这样呢?

我错过了什么?

序列化充满了陷阱。 这种forms的自动序列化支持使得类内部成为公共API的一部分(这就是为什么javadoc为你提供持久forms的类 )。

对于长期持久化,类必须能够解码这个表单,这就限制了对类devise所做的修改。 这打破封装。

序列化也可能导致安全问题。 通过能够序列化其引用的任何对象,类可以访问它通常不能(通过parsing结果字节数据)的数据。

还有其他的问题,如内部类的序列化forms没有很好的定义。

让所有的类可序列化会加剧这些问题。 查看有效的Java第二版 ,特别是项目74:明智地实施Serializable

我认为Java和.Net这两个人这一次错了,最好是使默认情况下一切可序列化,只需要标记那些不能安全序列化的类。

例如,在Smalltalk(一种在70年代创build的语言)中,每个对象默认都是可序列化的。 我不知道为什么在Java中这种情况不是这样,考虑到绝大多数对象可以安全地序列化,而其中的一些却不是。

将一个对象标记为可序列化(使用接口)并不会神奇地使该对象可序列化, 它始终是可序列化的,只是现在你expression了系统可以自己find的东西,所以我没有看到真正的好理由序列化就是现在的样子。

我认为这可能是devise师做出的一个糟糕的决定,或者系列化是事后的想法,或者平台从未准备好对所有对象进行安全一致的默认序列化。

并非所有的东西都是真正可序列化的 以networking套接字连接为例。 您可以序列化您的套接字对象的数据/状态,但活动连接的本质将会丢失。

Java中Serializable的主要作用是默认情况下使所有其他对象都不可序列化。 序列化是一个非常危险的机制,特别是在其默认实现中。 因此,就像在C ++中的友谊一样,它默认是closures的,即使花费很less的东西来进行序列化。

序列化增加了约束和潜在的问题,因为结构兼容性不保证。 这是好的,它是默认closures。

我不得不承认,我已经看到了非常less的非平凡类,在那里标准的序列化做我想做的事情。 特别是在复杂的数据结构的情况下。 所以你花费在课堂上的努力可以使得这个类可以正确地使用,这就增加了界面的成本。

对于某些类,特别是那些代表更像File,Socket,Thread或DB连接的物理类的实例,序列化实例是毫无意义的。 对于其他许多人来说,序列化可能是有问题的,因为它破坏了唯一性约束,或者只是迫使你处理不同版本的类的实例,而这些实例可能不是你想要的。

可以说,默认情况下,一切都是可序列化的,并且通过关键字或标记接口使类不可序列化可能会更好 – 但是,那些应该使用该选项的人可能不会考虑它。 就这样,如果你需要实现Serializable,你将会被exception告诉。

我认为虽然是确保你作为程序员知道你的对象是我的序列化的。

显然,在一些初步的devise中,所有的东西都是可序列化的,但是由于安全性和正确性的考虑,最终的devise结果如我们所知。

来源: 为什么类必须实现Serializable才能写入ObjectOutputStream? 。

必须明确地陈述某个类的实例是可序列化的,如果你允许的话,这种语言会迫使你去思考。 对于简单的值对象序列化是微不足道的,但在更复杂的情况下,你需要真正的思考。

通过依靠JVM的标准序列化支持,您可以将自己暴露于各种令人讨厌的版本问题。

唯一性,对“真实”资源,定时器和大量其他types工件的引用不是序列化的候选对象。

阅读这个来理解Serializable接口,以及为什么我们只需要less量的Serializable类,而且我们还要仔细考虑如何使用transient关键字来防止存储过程中的几个字段。

http://www.codingeek.com/java/io/object-streams-serialization-deserialization-java-example-serializable-interface/

那么,我的回答是,这是没有理由的。 从您的意见,我可以看到,你已经知道了。 其他语言愉快地尝试序列化所有不会在树上跳转到10的数据。一个对象应该默认是可序列化的。

所以,你基本上需要做的是自己阅读第三方类的所有属性。 或者,如果这是你的一个select:反编译,把那该死的关键字,并重新编译。

Java中有些东西不能被序列化,因为它们是运行时特定的。 像stream,线程,运行时等,甚至一些GUI类(连接到底层操作系统)都不能被序列化。

虽然我同意其他答案中提出的观点,但真正的问题在于反序列化:如果类定义发生变化,那么反序列化将不起作用。 永远不要修改现有的字段是图书馆作者做出的一个非常重要的承诺! 保持API兼容性就足够了。

一个需要被保存到一个文件或其他媒体的类必须实现Serializable接口,以便JVM可以允许该类对象被序列化。 为什么Object类没有被序列化,那么没有一个类需要实现接口,毕竟JVM只在我使用ObjectOutputStream时序列化类,这意味着控制权仍然在我手中,让JVM序列化。

为什么Object类在默认情况下是不可序列化的,因为类版本是主要问题。 因此,每个对序列化感兴趣的类都必须明确标记为Serializable并提供版本号serialVersionUID。

如果没有提供serialVersionUID ,那么在反序列化对象时,我们会得到意外的结果,这就是为什么如果serialVersionUID不匹配,JVM会抛出InvalidClassException 。 因此,每个类都必须实现Serializable接口并提供serialVersionUID以确保两端呈现的Class是相同的。