序列化代理模式示例

这篇博客探讨了如何使用序列化代理模式解决在Java中处理非序列化父类时遇到的问题。通过示例展示了如何创建内部类SerializationProxy来保存逻辑状态,并利用writeReplace和readResolve方法确保在序列化和反序列化过程中的正确性。

有些书可以极大地改变您的生活。 其中一本是Joshua Bloch撰写的“ Effective Java” 。 在下面您可能会发现一些小的实验,该实验的灵感来自于本书的第11章“串行化”。

假设我们有一个为继承而设计的类,它本身不是可序列化的 ,并且没有无参数的构造函数,如以下示例所示:

public class CumbersomePoint {

    private String name;

    private double x;

    private double y;

    protected CumbersomePoint(double x, double y, String name) {
        this.x = x;
        this.y = y;
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public double getX() {
        return x;
    }

    public double getY() {
        return y;
    }

    ...
}

现在,当我们扩展此类时,例如通过以下方式:

public class ConvenientPoint extends CumbersomePoint implements Serializable {

    public ConvenientPoint(double x, double y, String name) {
        super(x, y, name);
    }

    ...
}

并尝试序列化然后反序列化任何ConvenientPoint实例,我们将很快遇到漂亮的InvalidClassException ,抱怨没有有效的构造函数。 在您应用称为序列化代理模式的技术之前,情况看起来有点绝望。

首先,将内部类添加到ConvenientPoint类中:

private static class SerializationProxy implements Serializable {

        private String name;

        private double x;

        private double y;

        public SerializationProxy(ConvenientPoint point) {
            this.name = point.getName();
            this.x = point.getX();
            this.y = point.getY();
        }

        private Object readResolve() {
            return new ConvenientPoint(x, y, name);
        }

    }

SerializationProxy类将表示封闭类实例的逻辑状态。 我们还必须向ConvenientPoint类添加以下方法:

private Object writeReplace() {
        return new SerializationProxy(this);
    }

现在,当ConvenientPoint实例将被序列化时,由于writeReplace方法,它将提名其替换对象– SerializationProxy实例将被序列化而不是ConvenientPoint

另一方面,当序列化代理将被反序列化时, readResolve方法的使用将提名其替代品,即ConvenientPoint实例。

如您所见,无论缺少不可序列化的父类的无参数构造函数,我们都使ConvenientPoint可序列化。

在本文的结尾,再说一遍–如果要防止破坏由构造函数强制执行的类不变式,可以使用序列化代理模式 (在我们的示例中为ConvenientPoint)在类中添加以下方法:

private void readObject(ObjectInputStream stream) throws InvalidObjectException {
        throw new InvalidObjectException("Use Serialization Proxy instead.");
    }

它将防止封闭类的反序列化。

翻译自: https://www.javacodegeeks.com/2014/06/serialization-proxy-pattern-example.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值