`
leonzhx
  • 浏览: 786046 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Item 78: Consider serialization proxies instead of serialized instances

阅读更多

1.  The serialization proxy pattern is reasonably straightforward. First, design a private static nested class of the serializable class that concisely represents the logical state of an instance of the enclosing class. This nested class, known as the serialization proxy, should have a single constructor, whose parameter type is the enclosing class. This constructor merely copies the data from its argument: it need not do any consistency checking or defensive copying. By design, the default serialized form of the serialization proxy is the perfect serialized form of the enclosing class. Both the enclosing class and its serialization proxy must be declared to implement Serializable. Then add the following writeReplace method to the enclosing class:

// writeReplace method for the serialization proxy pattern
private Object writeReplace() {
    return new SerializationProxy(this);
} 

 

The presence of this method causes the serialization system to emit a SerializationProxy instance instead of an instance of the enclosing class. In other words, the writeReplace method translates an instance of the enclosing class to its serialization proxy prior to serialization. With this writeReplace method in place, the serialization system will never generate a serialized instance of the enclosing class, but an attacker might fabricate one in an attempt to violate the class’s invariants. To guarantee that such an attack would fail, merely add this readObject method to the enclosing class:

// readObject method for the serialization proxy pattern
private void readObject(ObjectInputStream stream) throws InvalidObjectException {
    throw new InvalidObjectException("Proxy required");
}

 

Finally, provide a readResolve method on the SerializationProxy class that returns a logically equivalent instance of the enclosing class. The presence of this method causes the serialization system to translate the serialization proxy back into an instance of the enclosing class upon deserialization. This readResolve method creates an instance of the enclosing class using only its public API. It largely eliminates the extralinguistic character of serialization, because the deserialized instance is created using the same constructors, static factories, and methods as any other instance.

 

2.  There is another way in which the serialization proxy pattern is more powerful than defensive copying. The serialization proxy pattern allows the deserialized instance to have a different class from the originally serialized instance.

 

3.  EnumSet has no public constructors, only static factories. From the client’s perspective, they return EnumSet instances, but in fact, they return one of two subclasses, depending on the size of the underlying enum type. If the underlying enum type has sixty-four or fewer elements, the static factories return a RegularEnumSet; otherwise, they return a JumboEnumSet:

// EnumSet's serialization proxy
private static class SerializationProxy <E extends Enum<E>> implements Serializable {
    // The element type of this enum set.
    private final Class<E> elementType;
    // The elements contained in this enum set.
    private final Enum[] elements;
    SerializationProxy(EnumSet<E> set) {
        elementType = set.elementType;
        elements = set.toArray(EMPTY_ENUM_ARRAY); 
    }
    private Object readResolve() {
        EnumSet<E> result = EnumSet.noneOf(elementType);
        for (Enum e : elements)
            result.add((E)e);
        return result;
    }
    private static final long serialVersionUID = 362491234563181265L;
}

 

4.  The serialization proxy pattern has two limitations. It is not compatible with classes that are extendable by their clients. Also, it is not compatible with some classes whose object graphs contain circularities: if you attempt to invoke a method on an object from within its serialization proxy’s readResolve method, you’ll get a ClassCastException, as you don’t have the object yet, only its serialization proxy.

 

分享到:
评论

相关推荐

    Effective Java 3rd edition(Effective Java第三版英文原版)附第二版

    目录如下: 1 Introduction 2 Creating and Destroying Objects Item 1: Consider static factory methods instead of constructors ...Item 90: Consider serialization proxies instead of serialized instances

    Boost::Serialization存储C++对象

    Boost::Serialization是C++库中的一个模块,它提供了一种序列化和反序列化对象的能力。这个库使得能够将复杂的C++对象结构保存到文件、数据库或者网络流中,然后在需要时重新加载,这对于数据持久化、版本控制以及跨...

    C++11 下使用 Boost.Serialization 库实现智能指针的序列化

    Boost.Serialization库是C++社区广泛使用的序列化工具,它提供了丰富的功能来处理各种类型的对象,包括智能指针。在C++11及更高版本中,智能指针(如`std::unique_ptr`,`std::shared_ptr`和`std::scoped_ptr`)被...

    LVDS Source Synchronous DDR Deserialization, Xilinx 7 Series FPG

    LVDS源同步DDR解串行化是Xilinx 7系列FPGA中的一个重要功能,它允许在每个通道上实现高达1,600 Mb/s的速度,具体速度取决于所使用的器件家族和速度等级。这一技术主要利用了7系列FPGA内置的输入串行到并行转换器...

    kotlinx-serialization-compiler-plugin.jar

    kotlinx-serialization-compiler-plugin.jar

    Effective C#

    **Item 1: Use Properties Instead of Accessible Data Members** - **Benefits:** Using properties instead of public data members enhances encapsulation and allows for validation logic, lazy loading, and...

    gtsam4.0.3库

    GTSAM(Global Trajectory Synchronization and Smoothing)是一个C++库,专注于估计全局一致的序列模型,广泛应用于机器人定位、SLAM(Simultaneous Localization and Mapping)问题以及多传感器融合等领域。...

    .NET: Xml.Serialization常用对象导图

    .NET框架中,System.Xml.Serialization 命名空间包含着用来将对象序列化为XML的文本或流的对象。

    xml_lib.rar_Boost_boost xml_lib xml_xml.lib

    在本压缩包“xml_lib.rar”中,你将找到关于如何利用Boost库处理XML文件的一些资源,特别是Boost的XML库(Boost.Serialization的一部分),以及可能的预编译库文件“xml.lib”。 Boost库中的XML支持主要由Boost....

    aviator-5.4.1.jar

    feat: impl serialization for compiled expression by @killme2008 in #524, close #451 The expression serialize example fix: elsif parser by @killme2008 in #574, close #554 #566 (fix): check innerClazz ...

    System.Runtime.Serialization.DLL.zip

    《深入理解System.Runtime.Serialization.DLL及其在.NET框架中的作用》 在.NET框架中,`System.Runtime.Serialization`命名空间是处理序列化和反序列化的核心组件,而`System.Runtime.Serialization.dll`则是这个...

    sirenix.serialization.dll

    sirenix.serialization.dll

    PyPI 官网下载 | oslo.serialization-2.2.0.tar.gz

    **PyPI 官网下载 | oslo.serialization-2.2.0.tar.gz** PyPI(Python Package Index)是Python开发者获取和分享开源软件包的主要平台。`oslo.serialization` 是一个在PyPI上发布的Python库,它专注于数据序列化和反...

    Python库 | oslo.serialization-2.21.0-py2.py3-none-any.whl

    资源分类:Python库 所属语言:Python 资源全名:oslo.serialization-2.21.0-py2.py3-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    Android代码-kotlinx.serialization

    Kotlin serialization consists of a compiler plugin, which automatically produces visitor code for classes, and runtime library, which uses generated code to serialize objects without reflection. ...

    System.Runtime.Serialization.dll

    《深入解析System.Runtime.Serialization.dll》 System.Runtime.Serialization.dll是.NET Framework中的一个重要组件,它属于Microsoft的基础类库,主要负责数据序列化和反序列化的功能。数据序列化是将对象的状态...

    hystrix-serialization-1.5.18.jar

    hystrix-serialization-1.5.18.jar

    ABAP调用外部(第三方系统)WebService

    ### ABAP调用外部(第三方系统)WebService #### 基础知识 在开始学习如何在SAP系统中调用外部WebService之前,首先需要理解一些基本概念和技术。 1. **XML (可扩展标记语言):** XML是一种通用的、平台独立的数据...

Global site tag (gtag.js) - Google Analytics