【发布时间】:2015-01-28 00:53:29
【问题描述】:
我读到我们应该只序列化对象的逻辑部分。
当一个对象的物理的时候使用默认的序列化形式 表示与其逻辑数据内容有很大不同 缺点四:
...//它们与默认的序列化形式有关,与 主题
//关于Strings的链表:
合理的序列化形式 for StringList 只是列表中字符串的数量,后跟 由琴弦本身。这构成了逻辑数据 由一个 StringList 表示,去掉了它的物理细节 表示。
Effective Java(第 2 版),第 75 条
在链表的情况下,这意味着我们不应该序列化任何实现细节,如节点关系,而实际上只是“元素列表”。
我有链表实现,想在里面实现序列化代理模式(Effective Java (2nd Edition), Item 78),但也不要违反规则更多。还有一句话:
序列化代理模式相当简单。一、设计可序列化类的私有静态嵌套类 简洁地表示实例的逻辑状态 封闭类。这个嵌套类,称为序列化代理, 应该有一个构造函数,其参数类型是 封闭类。此构造函数仅从其复制数据 论点:它不需要做任何一致性检查或防御 复制。根据设计,序列化的默认序列化形式 proxy 是封闭类的完美序列化形式。
那么在序列化代理类中序列化对象的逻辑状态是否正确(正如我在下面所做的那样)或者例如序列化作为实现细节的列表的头节点也是正确的?
注意:List 接口和LinkedList 类是我自己的实现,而不是java.util。
//...
private static class SerializationProxy<E> implements Serializable {
private final E[] elements;
SerializationProxy(List<? extends E> list) {
elements = list.toArray(Object.class); //returns array with all elements
}
private Object readResolve() {
return new LinkedList<E>(elements); //constructor that take array and wraps it back in LinkedList
}
private static final long serialVersionUID = 123131234141423234L;
}
private void readObject(ObjectInputStream stream)
throws InvalidObjectException {
throw new InvalidObjectException("Proxy required");
}
private Object writeReplace() {
return new SerializationProxy<E>(this); //pass enclosing class for proxy serializtion
}
//...
如果有什么不清楚的地方full implementation. 提前谢谢。
【问题讨论】:
-
只是序列化列表。你不需要这样做。但是你在做什么没有意义。它将无限期地追索。代理不需要
writeReplace()方法,它需要readResolve()方法。 -
@EJP 我的代理有
readResolve(),readResolve()属于封闭类。我忘了注意List是我自己的界面,不是java.util,对不起。 -
真的没有任何区别。只需将您的
List类设为Serializable。不需要任何这些,除非您计划拥有包含数万个元素的列表。您似乎做对了发布您的编辑,至少您在这里发布的内容。没有人会追逐链接。 -
@EJP 我这样做是出于教育目的,想学习如何正确使用这种模式。如果逻辑数据与其物理表示(链表的情况)不同并且我们想确保安全性,我们不应该简单地创建类
implements Serializable。 -
好吧,试试看会发生什么。打印一些痕迹,以便您了解发生了什么。
标签: java serialization