Java 自定义表单的序列化代理?

Java 自定义表单的序列化代理?,java,file,serialization,file-io,Java,File,Serialization,File Io,如果我使用的是序列化代理模式,我应该为包含的类提供一个自定义的writeObject方法,还是只提供代理?我是否应该为代理使用自定义表单?我已经阅读了《有效Java》中有关序列化的章节,但不清楚自定义表单和代理模式。当您使用序列化代理模式时,原始类的实例永远不会使用“正常”序列化机制进行序列化。因此,如果原始类有一个writeObject实现,它将永远不会被调用 虽然您不需要writeObject方法,但您可能应该在原始类中编写readObject方法。如果类的旧序列化实例是在引入代理之前序列化

如果我使用的是序列化代理模式,我应该为包含的类提供一个自定义的
writeObject
方法,还是只提供代理?我是否应该为代理使用自定义表单?我已经阅读了《有效Java》中有关序列化的章节,但不清楚自定义表单和代理模式。

当您使用序列化代理模式时,原始类的实例永远不会使用“正常”序列化机制进行序列化。因此,如果原始类有一个
writeObject
实现,它将永远不会被调用

虽然您不需要
writeObject
方法,但您可能应该在原始类中编写
readObject
方法。如果类的旧序列化实例是在引入代理之前序列化的,则它们可能存在。或者,可能有人伪造了一个字节流,看起来像原始类的常规序列化形式。反序列化将绕过代理,并可能创建原始类的格式错误的实例。要防止这种情况,请无条件地从原始类的
readObject
方法抛出异常,以防止任何反序列化绕过代理。(这在有效的Java中提到过,但重要的是我觉得应该在这里重复。)

至于串行代理的自定义形式,这并不是绝对必要的。有效的Java建议串行代理类的设计应足够简单明了,以便可以使用默认的序列化形式。如果这对您有效,很好,您可以使用默认表单。但我开始看到的另一种模式是,使用单个序列化代理作为多个不同可序列化类的代理。在这种情况下,代理类不是嵌套类,而是同一个包中的包私有类。代理可能希望有一个自定义的序列化表单,这样它就可以根据它是哪个类的代理而改变所写入的序列化数据


JDK中新的
java.time
类的序列化就是这样做的,它使用一个串行代理来处理多个数据类。查看该文件以了解如何执行此操作。不过,这有点复杂,因为它使用
Externalizable
接口而不是特殊的序列化方法,并且它委托回数据类来执行读写操作。但是您可以看到这些原则在起作用。

原始类应该有一个返回代理类实例的
writeReplace()
方法,代理类应该有一个返回原始类实例的
readResolve()
方法

我应该为包含的类提供自定义writeObject方法吗

没有

还是只是代理

没有

我是否应该为代理使用自定义表单

不可以。让代理类尽可能简单,即POJO