Java中可序列化和可外部化的区别是什么?


当前回答

一些差异:

For Serialization there is no need of default constructor of that class because Object because JVM construct the same with help of Reflection API. In case of Externalization contructor with no arg is required, because the control is in hand of programmar and later on assign the deserialized data to object via setters. In serialization if user want to skip certain properties to be serialized then has to mark that properties as transient, vice versa is not required for Externalization. When backward compatiblity support is expected for any class then it is recommended to go with Externalizable. Serialization supports defaultObject persisting and if object structure is broken then it will cause issue while deserializing.

其他回答

要添加到其他答案,请实现java.io。Serializable,您可以获得类对象的“自动”序列化功能。不需要实现任何其他逻辑,它就可以工作了。Java运行时将使用反射来确定如何封送和解封送对象。

In earlier version of Java, reflection was very slow, and so serializaing large object graphs (e.g. in client-server RMI applications) was a bit of a performance problem. To handle this situation, the java.io.Externalizable interface was provided, which is like java.io.Serializable but with custom-written mechanisms to perform the marshalling and unmarshalling functions (you need to implement readExternal and writeExternal methods on your class). This gives you the means to get around the reflection performance bottleneck.

在Java的最新版本(当然是1.3以后)中,反射的性能比以前好得多,所以这不是一个大问题。我怀疑在现代JVM中,您很难从Externalizable中获得有意义的好处。

此外,内置的Java序列化机制并不是唯一的,您可以获得第三方替代机制,例如JBoss serialization,它要快得多,并且是默认的替代机制。

Externalizable一个很大的缺点是你必须自己维护这个逻辑——如果你在你的类中添加、删除或改变一个字段,你必须改变你的writeExternal/ readeexternal方法来解释它。

总之,Externalizable是Java 1.1时代的遗留物。真的没有必要了。

序列化使用某些默认行为来存储对象并稍后重新创建对象。您可以指定以何种顺序或如何处理引用和复杂的数据结构,但最终还是要为每个基本数据字段使用默认行为。

在极少数情况下使用外部化,您确实希望以完全不同的方式存储和重新构建对象,并且不使用数据字段的默认序列化机制。例如,假设您有自己独特的编码和压缩方案。

实际上并没有提供Externalizable接口来优化序列化进程的性能!而是提供实现您自己的自定义处理的方法,并为对象及其超类型提供对流的格式和内容的完全控制!

这方面的例子是AMF (ActionScript Message Format)远程处理的实现,通过网络传输本机操作脚本对象。

Serializable和Externalizable之间的主要区别

Marker interface: Serializable is marker interface without any methods. Externalizable interface contains two methods: writeExternal() and readExternal(). Serialization process: Default Serialization process will be kicked-in for classes implementing Serializable interface. Programmer defined Serialization process will be kicked-in for classes implementing Externalizable interface. Maintenance: Incompatible changes may break serialisation. Backward Compatibility and Control: If you have to support multiple versions, you can have full control with Externalizable interface. You can support different versions of your object. If you implement Externalizable, it's your responsibility to serialize super class public No-arg constructor: Serializable uses reflection to construct object and does not require no arg constructor. But Externalizable demands public no-arg constructor.

更多细节请参考Hitesh Garg的博客。

https://docs.oracle.com/javase/8/docs/platform/serialization/spec/serialTOC.html

默认序列化有点冗长,并且假定序列化对象的使用场景尽可能广泛,因此默认格式(Serializable)用关于序列化对象的类的信息注释结果流。

外部化使对象流的生产者能够完全控制精确的类元数据(如果有的话),而不仅仅是类所需的最小标识(例如它的名称)。这在某些情况下显然是可取的,比如在封闭环境中,对象流的生产者和消费者(从流中具体化对象)是匹配的,关于类的额外元数据没有任何作用,而且会降低性能。

此外(正如Uri指出的那样)外部化还提供了对与Java类型对应的流中数据编码的完全控制。对于(一个人为的)例子,您可能希望将布尔值true记录为“Y”,将false记录为“N”。外部化可以让你做到这一点。