为什么 Java 需要可串行化的接口?

我们大量使用序列化,并且必须在我们使用的每个对象上指定可序列化的标记是一种负担。尤其是我们无法改变的第三方课堂。

The question is: since Serializable is an empty interface and Java provides robust serialization once you add implements Serializable - why didn't they make everything serializable and that's it?

我错过了什么?

65539 次浏览

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

我认为这样做是为了确保你,作为程序员,知道你的对象我是序列化的。

For some classes, especially those that represent something more physical like a File, a Socket, a Thread, or a DB connection, it makes absolutely no sense to serialize instances. For many others, Serialization may be problematic because it destroys uniqueness constraints or simply forces you to deal with instances of different versions of a class, which you may not want to.

Arguably, it might have been better to make everything Serializable by default and make classes non-serializable through a keyword or marker interface - but then, those who should use that option probably would not think about it. The way it is, if you need to implement Serializable, you'll be told so by an Exception.

Serialization is fraught with pitfalls. Automatic serialization support of this form makes the class internals part of the public API (which is why javadoc gives you the 类的持久化形式).

对于长期持久性,类必须能够解码此表单,这限制了对类设计的更改。这破坏了封装。

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

还有其他问题,例如内部类的序列化形式没有得到很好的定义。

使所有的类都可序列化会加剧这些问题,看看 Effective Java Second Edition,特别是 项目74: 明智地实施可序列化

我觉得 Java 和。网民这次搞错了,如果默认情况下所有内容都是可序列化的,只需要标记那些不能安全序列化的类就更好了。

例如,在 Smalltalk (一种创建于70年代的语言)中,每个对象在默认情况下都是可序列化的。我不知道为什么在 Java 中不是这种情况,因为绝大多数对象序列化是安全的,只有少数对象是不安全的。

Marking an object as serializable (with an interface) doesn't magically make that object serializable, 它一直都是可以连载的, it's just that now you expressed something that the system could have found on his own, so I see no real good reason for serialization being the way it is now.

我认为这要么是设计人员做出的一个糟糕的决定,要么是事后才想到序列化,要么是平台从来没有准备好默认情况下对所有对象进行安全和一致的序列化。

Well, my answer is that this is for no good reason. And from your comments I can see that you've already learned that. Other languages happily try serializing everything that doesn't jump on a tree after you've counted to 10. An Object should default to be serializable.

所以,基本上你需要做的就是自己读取你的第三方类的所有属性。或者,如果可以的话: 反编译,把该死的关键字放在那里,然后重新编译。

The main role of Serializable in Java is to actually make, by default, all other objects nonserializable. Serialization is a very dangerous mechanism, especially in its default implementation. Hence, like friendship in C++, it is off by default, even if it costs a little to make things serializable.

序列化增加了约束和潜在的问题,因为没有保证结构兼容性。它默认关闭是件好事。

我必须承认,我见过很少有非平凡的类,其中标准序列化可以完成我希望它完成的任务。特别是在复杂数据结构的情况下。因此,使类可序列化所花费的精力使添加接口的成本相形见绌。

Having to state explicitely that instances of a certain class are Serializable the language forces you to think about if you you should allow that. For simple value objects serialization is trivial, but in more complex cases you need to really think things through.

By just relying on the standard serialization support of the JVM you expose yourself to all kinds of nasty versioning issues.

唯一性、对“真实”资源的引用、计时器和许多其他类型的工件都不适合序列化。

Java 中有些东西就是做不到 因为它们是特定于运行时的。像流、线程、运行时、, 等等,甚至一些 GUI 类(连接到底层操作系统)也不能 被连载。

显然,在一些初步设计中,所有东西都是可连续化的,但是由于安全性和正确性的考虑,最终的设计结果是众所周知的。

资料来源: 为什么类必须实现 Serialable 才能写入 ObjectOutputStream?

While I agree with the points made in other answers here, the real problem is with deserialisation: If the class definition changes then there's a real risk the deserialisation won't work. Never modifying existing fields is a pretty major commitment for the author of a library to make! Maintaining API compatibility is enough of a chore as it is.

Read this to understand Serializable Interface and why we should make only few classes Serializable and also we shopuld take care where to use transient keyword in case we want to remove few fields from the storing procedure.

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

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

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

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