我正在浏览this article以了解有关Java序列化过程的更多信息。在使用readObject/writeObject
时,我可以看到两个用例:
writeObject
在序列化之前加密字节码。从安全的角度来看,这是件好事。readObject
来执行需要在反序列化后立即执行的任何特定代码段,当然从#1开始,我们甚至可以使用readObject
来解密字节代码在序列化对象时被删除。在编写自定义readObject / writeObject方法时序列化/反序列化对象时是否还有其他实际情况?或者如果你能指出我能看到readObject / writeObject的一些不错的实际用途的地方吗?
答案 0 :(得分:15)
自定义readObject
方法也很有用。
BTW,请查看Effective Java, Chapter 11(我不确定第2版中的章节/项目编号是什么。)。这是一篇关于序列化的精彩读物。
答案 1 :(得分:5)
出于性能原因或向后兼容性原因,或者因为要序列化的字段不是Serializable,您可以实现自己的readObject / writeObject。
对于readObject / writeObject的好例子,我会查看JDK附带的源代码。或者我会尝试http://www.google.co.uk/search?q=readObject+writeObject+examples
答案 2 :(得分:4)
使用自定义序列化可能有几个原因:
仅举几例,但我相信还有更多。
答案 3 :(得分:3)
我可以通过使用基于CipherOutputsStream的ObjectOutputStream来更好地解密。
writeObject / readObject最重要的用途是,如果要在多个代码修订版上保持Serialization稳定。您的内部表示(成员变量)可能会更改,但序列化必须保持稳定,因为您与之通信的旧系统(例如,通过从文件中读取旧数据)。
但我更喜欢Externalizable接口,因为它更容易使用(没有隐式调用和只有jvm知道的方法)。
答案 4 :(得分:3)
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private int empno;
private String ename;
private String job;
// setter & getter
@Override
public String toString() {
return "Employee [empno=" + empno + ", ename=" + ename + ", job=" + job
+ "]";
}
private void writeObject(ObjectOutputStream out) throws IOException {
// default serialization
// out.defaultWriteObject();
// custom serialization
out.writeInt(empno);
out.writeUTF(ename);
// out.writeUTF(job); //job will not serialize
}
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
// default deSerialization
// in.defaultReadObject();
// custom deSerialization
empno = in.readInt();
ename = in.readUTF();
// this.job = in.readUTF();
}
}
答案 5 :(得分:1)
writeObject() 和 readObject() 方法也用于防止对象序列化。
当一个 Super 类实现 Serializable 时,它的所有子类默认都是可序列化的。但是,如果您希望子类不可序列化,请重写子类中的 writeObject() 和 readObject() 方法,如下所示
class Parent implements Serailizable
{
int id;
}
class child extends Parent
{
String name;
private void writeObject(ObjectOutputStream out) throws NotSerializableException
{
throw new NotSerializableException();
}
private void readObject(ObjectInputStream in) throws NotSerializableException
{
throw new NotSerializableException();
}
}
现在子类的对象无法序列化。