Java中可序列化和可外部化的区别是什么?
当前回答
There are so many difference exist between Serializable and Externalizable but when we compare difference between custom Serializable(overrided writeObject() & readObject()) and Externalizable then we find that custom implementation is tightly bind with ObjectOutputStream class where as in Externalizable case , we ourself provide an implementation of ObjectOutput which may be ObjectOutputStream class or it could be some other like org.apache.mina.filter.codec.serialization.ObjectSerializationOutputStream
如果是Externalizable接口
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeUTF(key);
out.writeUTF(value);
out.writeObject(emp);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
this.key = in.readUTF();
this.value = in.readUTF();
this.emp = (Employee) in.readObject();
}
**In case of Serializable interface**
/*
We can comment below two method and use default serialization process as well
Sequence of class attributes in read and write methods MUST BE same.
// below will not work it will not work .
// Exception = java.io.StreamCorruptedException: invalid type code: 00\
private void writeObject(java.io.ObjectOutput stream)
*/
private void writeObject(java.io.ObjectOutputStream Outstream)
throws IOException {
System.out.println("from writeObject()");
/* We can define custom validation or business rules inside read/write methods.
This way our validation methods will be automatically
called by JVM, immediately after default serialization
and deserialization process
happens.
checkTestInfo();
*/
stream.writeUTF(name);
stream.writeInt(age);
stream.writeObject(salary);
stream.writeObject(address);
}
private void readObject(java.io.ObjectInputStream Instream)
throws IOException, ClassNotFoundException {
System.out.println("from readObject()");
name = (String) stream.readUTF();
age = stream.readInt();
salary = (BigDecimal) stream.readObject();
address = (Address) stream.readObject();
// validateTestInfo();
}
为了更好地解释,我添加了示例代码。请检查Externalizable的入/出对象情况。它们不直接绑定到任何实现。 其中Outstream/ stream与类紧密绑定。我们可以扩展ObjectOutputStream/ObjectInputStream,但使用起来有点困难。
其他回答
There are so many difference exist between Serializable and Externalizable but when we compare difference between custom Serializable(overrided writeObject() & readObject()) and Externalizable then we find that custom implementation is tightly bind with ObjectOutputStream class where as in Externalizable case , we ourself provide an implementation of ObjectOutput which may be ObjectOutputStream class or it could be some other like org.apache.mina.filter.codec.serialization.ObjectSerializationOutputStream
如果是Externalizable接口
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeUTF(key);
out.writeUTF(value);
out.writeObject(emp);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
this.key = in.readUTF();
this.value = in.readUTF();
this.emp = (Employee) in.readObject();
}
**In case of Serializable interface**
/*
We can comment below two method and use default serialization process as well
Sequence of class attributes in read and write methods MUST BE same.
// below will not work it will not work .
// Exception = java.io.StreamCorruptedException: invalid type code: 00\
private void writeObject(java.io.ObjectOutput stream)
*/
private void writeObject(java.io.ObjectOutputStream Outstream)
throws IOException {
System.out.println("from writeObject()");
/* We can define custom validation or business rules inside read/write methods.
This way our validation methods will be automatically
called by JVM, immediately after default serialization
and deserialization process
happens.
checkTestInfo();
*/
stream.writeUTF(name);
stream.writeInt(age);
stream.writeObject(salary);
stream.writeObject(address);
}
private void readObject(java.io.ObjectInputStream Instream)
throws IOException, ClassNotFoundException {
System.out.println("from readObject()");
name = (String) stream.readUTF();
age = stream.readInt();
salary = (BigDecimal) stream.readObject();
address = (Address) stream.readObject();
// validateTestInfo();
}
为了更好地解释,我添加了示例代码。请检查Externalizable的入/出对象情况。它们不直接绑定到任何实现。 其中Outstream/ stream与类紧密绑定。我们可以扩展ObjectOutputStream/ObjectInputStream,但使用起来有点困难。
序列化使用某些默认行为来存储对象并稍后重新创建对象。您可以指定以何种顺序或如何处理引用和复杂的数据结构,但最终还是要为每个基本数据字段使用默认行为。
在极少数情况下使用外部化,您确实希望以完全不同的方式存储和重新构建对象,并且不使用数据字段的默认序列化机制。例如,假设您有自己独特的编码和压缩方案。
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的博客。
基本上,Serializable是一个标记接口,它暗示一个类对于序列化是安全的,并且JVM决定它如何序列化。Externalizable包含两个方法,readExternal和writeExternal。Externalizable允许实现者决定如何序列化一个对象,而Serializable序列化对象是默认的方式。
实际上并没有提供Externalizable接口来优化序列化进程的性能!而是提供实现您自己的自定义处理的方法,并为对象及其超类型提供对流的格式和内容的完全控制!
这方面的例子是AMF (ActionScript Message Format)远程处理的实现,通过网络传输本机操作脚本对象。
推荐文章
- 指定的子节点已经有一个父节点。你必须先在子对象的父对象上调用removeView() (Android)
- 将流转换为字符串并返回
- 对于一个布尔字段,它的getter/setter的命名约定是什么?
- 如何获得当前屏幕方向?
- 如何在Android中渲染PDF文件
- 如何计算一个元素在列表中出现的次数
- c++中类似于java的instanceof
- 我如何解决错误“minCompileSdk(31)指定在一个依赖的AAR元数据”在本机Java或Kotlin?
- 如何POST表单数据与Spring RestTemplate?
- Mockito中检测到未完成的存根
- 我应该如何复制字符串在Java?
- “while(true)”循环有那么糟糕吗?
- 这个方法签名中的省略号(…)是干什么用的?
- Java:如何测试调用System.exit()的方法?
- 带有返回类型的Java方法在没有返回语句的情况下编译