【问题标题】:Serialization proxy序列化代理
【发布时间】: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


【解决方案1】:

在序列化代理类中序列化对象的逻辑状态是否正确(如下所示)

这就是你的引文所说的。

或者例如实现细节的列表头节点的序列化也是正确的?

这正是你的引文所警告的。

我不一定同意引用。例如,我原则上不反对序列化链接。可能有实际反对意见,例如递归深度,但那是另一回事。

很难理解为什么你必须发布这个问题,当你已经有一个受人尊敬的引用,当你已经实施了答案,这反过来表明你已经理解了你所阅读的内容。

【讨论】:

    猜你喜欢
    • 2017-05-14
    • 1970-01-01
    • 1970-01-01
    • 2020-01-22
    • 2012-02-12
    • 1970-01-01
    • 2010-12-30
    • 1970-01-01
    相关资源
    最近更新 更多