为什么 Java 需要 Serializable 接口?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/441196/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why Java needs Serializable interface?
提问by Yoni Roit
We work heavily with serialization and having to specify Serializable tag on every object we use is kind of a burden. Especially when it's a 3rd-party class that we can't really change.
我们在序列化方面做了大量工作,并且必须在我们使用的每个对象上指定 Serializable 标签是一种负担。特别是当它是一个我们无法真正改变的 3rd 方类时。
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?
问题是:既然 Serializable 是一个空接口,而一旦添加,Java 就提供了强大的序列化 implements Serializable
- 为什么它们不使所有东西都可序列化,仅此而已?
What am I missing?
我错过了什么?
采纳答案by McDowell
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 persisted forms of classes).
序列化充满了陷阱。这种形式的自动序列化支持使类内部成为公共 API 的一部分(这就是 javadoc 为您提供类的持久形式的原因)。
For long-term persistence, the class must be able to decode this form, which restricts the changes you can make to class design. This breaks encapsulation.
为了长期持久性,类必须能够解码这种形式,这限制了您可以对类设计进行的更改。这打破了封装。
Serialization can also lead to security problems. By being able to serialize any object it has a reference to, a class can access data it would not normally be able to (by parsing the resultant byte data).
序列化也会导致安全问题。通过能够序列化它所引用的任何对象,类可以访问它通常无法访问的数据(通过解析结果字节数据)。
There are other issues, such as the serialized form of inner classes not being well defined.
还有其他问题,例如内部类的序列化形式没有很好地定义。
Making all classes serializable would exacerbate these problems. Check out Effective Java Second Edition, in particular Item 74: Implement Serializable judiciously.
使所有类都可序列化会加剧这些问题。查看Effective Java 第二版,特别是第 74 条:明智地实现可序列化。
回答by Joel Coehoorn
Not everything is genuinely serializable. Take a network socket connection, for example. You could serialize the data/state of your socket object, but the essence of an active connection would be lost.
并非所有东西都是真正可序列化的。以网络套接字连接为例。您可以序列化套接字对象的数据/状态,但活动连接的本质将丢失。
回答by Milhous
I think the though was to make sure you, as the programmer, know that your object my be serialized.
我认为这是为了确保您作为程序员知道您的对象可以被序列化。
回答by Michael Borgwardt
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.
可以说,默认情况下使所有内容都可序列化并通过关键字或标记接口使类不可序列化可能会更好 - 但是,那些应该使用该选项的人可能不会考虑它。它的方式是,如果您需要实现 Serializable,您会被异常告知。
回答by Pop Catalin
I think both Java and .Net people got it wrong this time around, would have been better to make everything serializable by default and only need to mark those classes that can't be safely serialized instead.
我认为 Java 和 .Net 的人这次都弄错了,默认情况下让所有内容都可序列化会更好,而只需要标记那些不能安全序列化的类。
For example in Smalltalk (a language created in 70s) every object is serializable by default. I have no idea why this is not the case in Java, considering the fact that the vast majority of objects are safe to serialize and just a few of them aren't.
例如,在 Smalltalk(一种 70 年代创建的语言)中,默认情况下每个对象都是可序列化的。我不知道为什么在 Java 中情况并非如此,因为绝大多数对象都可以安全地序列化,而只有少数对象不是。
Marking an object as serializable (with an interface) doesn't magically make that object serializable, it was serializable all along, 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.
将对象标记为可序列化(使用接口)并不会神奇地使该对象可序列化,它一直是可序列化的,只是现在您表达了系统可以自己找到的东西,所以我看不出有什么好的理由序列化就是现在的样子。
I think it was either a poor decision made by designers or serialization was an afterthought, or the platform was never ready to do serialization by default on all objects safely and consistently.
我认为这要么是设计人员做出的错误决定,要么是事后的序列化,要么平台从未准备好在默认情况下安全且一致地对所有对象进行序列化。
回答by nes1983
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.
好吧,我的回答是,这没有充分的理由。从你的评论中我可以看出你已经学会了这一点。其他语言愉快地尝试在数到 10 后序列化所有不会跳到树上的东西。对象应该默认为可序列化的。
So, what you basically need to do is read all the properties of your 3rd-party class yourself. Or, if that's an option for you: decompile, put the damn keyword there, and recompile.
所以,你基本上需要做的是自己阅读你的 3rd-party 类的所有属性。或者,如果这是你的一个选择:反编译,把该死的关键字放在那里,然后重新编译。
回答by Uri
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.
Java 中 Serializable 的主要作用是实际上使所有其他对象在默认情况下不可序列化。序列化是一种非常危险的机制,尤其是在其默认实现中。因此,就像 C++ 中的友谊一样,默认情况下它是关闭的,即使使事情可序列化需要花费一点钱。
Serialization adds constraints and potential problems since structure compatibility is not insured. It is good that it is off by default.
由于不保证结构兼容性,序列化增加了约束和潜在问题。默认情况下它是关闭的,这很好。
I have to admit that I have seen very few nontrivial classes where standard serialization does what I want it to. Especially in the case of complex data structures. So the effort you'd spend making the class serializble properly dwarves the cost of adding the interface.
我不得不承认,我见过很少有标准序列化按照我想要的方式执行的非平凡类。特别是在复杂数据结构的情况下。因此,您为使类可序列化而付出的努力使添加接口的成本相形见绌。
回答by Jeroen van Bergen
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.
仅仅依靠 JVM 的标准序列化支持,您就会面临各种令人讨厌的版本控制问题。
Uniqueness, references to 'real' resources, timers and lots of other types of artifacts are NOT candidates for serialization.
唯一性、对“真实”资源的引用、计时器和许多其他类型的工件都不是序列化的候选对象。
回答by Jeroen van Bergen
There are some things in Java that simply cannot be serialized because they are runtime specific. Things like streams, threads, runtime, etc. and even some GUI classes (which are connected to the underlying OS) cannot be serialized.
Java 中有一些东西根本无法序列化,因为它们是特定于运行时的。诸如流、线程、运行时等,甚至一些 GUI 类(连接到底层操作系统)都无法序列化。
回答by cic
Apparently everything was serializable in some preliminary designs, but because of security and correctness concerns the final design ended up as we all know.
显然,在一些初步设计中,一切都是可序列化的,但由于安全性和正确性的考虑,最终的设计以众所周知的方式结束。
Source: Why must classes implement Serializable in order to be written to an ObjectOutputStream?.