1. A major cost of implementing Serializable is that it decreases the flexibility to change a class’s implementation once it has been released. When a class implements Serializable, its byte-stream encoding (or serialized form) becomes part of its exported API. Once you distribute a class widely, you are generally required to support the serialized form forever, just as you are required to support all other parts of the exported API.
2. If you accept the default serialized form, the class’s private and package-private instance fields become part of its exported API, and the practice of minimizing access to fields loses its effectiveness as a tool for information hiding.
3. It is possible to change the internal representation while maintaining the original serialized form (using ObjectOutputStream.putFields and ObjectInputStream.readFields), but it can be difficult and leaves visible warts in the source code. Therefore, you should carefully design a high-quality serialized form that you are willing to live with for the long haul.
4. Every serializable class has a unique identification number associated with it. If you do not specify this number explicitly by declaring a static final long field named serialVersionUID, the system automatically generates it at runtime by applying a complex procedure to the class. The automatically generated value is affected by the class’s name, the names of the interfaces it implements, and all of its public and protected members. If you change any of these things in any way, the automatically generated serial version UID changes. If you fail to declare an explicit serial version UID, compatibility will be broken, resulting in an InvalidClassException at runtime.
5. A second cost of implementing Serializable is that it increases the likelihood of bugs and security holes. Normally, objects are created using constructors; serialization is an extralinguistic mechanism for creating objects. Whether you accept the default behavior or override it, deserialization is a “hidden constructor” with all of the same issues as other constructors. Relying on the default deserialization mechanism can easily leave objects open to invariant corruption and illegal access.
6. A third cost of implementing Serializable is that it increases the testing burden associated with releasing a new version of a class. When a serializable class is revised, it is important to check that it is possible to serialize an instance in the new release and deserialize it in old releases, and vice versa.
7. As a rule of thumb, value classes such as Date and BigInteger should implement Serializable, as should most collection classes. Classes representing active entities, such as thread pools, should rarely implement Serializable.
8. Classes designed for inheritance should rarely implement Serializable, and interfaces should rarely extend it. Violating this rule places a significant burden on anyone who extends the class or implements the interface. Classes designed for inheritance that do implement Serializable include Throwable, Component, and HttpServlet. Throwable implements Serializable so exceptions from remote method invocation (RMI) can be passed from server to client. Component implements Serializable so GUIs can be sent, saved, and restored. HttpServlet implements Serializable so session state can be cached.
9. If a class that is designed for inheritance is not serializable, it may be impossible to write a serializable subclass. Specifically, it will be impossible if the superclass does not provide an accessible parameterless constructor. Therefore, you should consider providing a parameterless constructor on nonserializable classes designed for inheritance. Naively adding a parameterless constructor and a separate initialization method to a class whose remaining constructors establish its invariants would complicate the state space, increasing the likelihood of error. Here is a way to add a parameterless constructor to a nonserializable extendable class that avoids these deficiencies:
// Nonserializable stateful class allowing serializable subclass public abstract class AbstractFoo { private int x, y; // Our state // This enum and field are used to track initialization private enum State { NEW, INITIALIZING, INITIALIZED }; private final AtomicReference<State> init = new AtomicReference<State>(State.NEW); public AbstractFoo(int x, int y) { initialize(x, y); } // This constructor and the following method allow // subclass's readObject method to initialize our state. protected AbstractFoo() { } protected final void initialize(int x, int y) { if (!init.compareAndSet(State.NEW, State.INITIALIZING)) throw new IllegalStateException("Already initialized"); this.x = x; this.y = y; ... // Do anything else the original constructor did init.set(State.INITIALIZED); } // These methods provide access to internal state so it can // be manually serialized by subclass's writeObject method. protected final int getX() { checkInit(); return x; } protected final int getY() { checkInit(); return y; } // Must call from all public and protected instance methods private void checkInit() { if (init.get() != State.INITIALIZED) throw new IllegalStateException("Uninitialized"); } ... // Remainder omitted } // Serializable subclass of nonserializable stateful class public class Foo extends AbstractFoo implements Serializable { private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); // Manually deserialize and initialize superclass state int x = s.readInt(); int y = s.readInt(); initialize(x, y); } private void writeObject(ObjectOutputStream s) throws IOException { s.defaultWriteObject(); // Manually serialize superclass state s.writeInt(getX()); s.writeInt(getY()); } // Constructor does not use the fancy mechanism public Foo(int x, int y) { super(x, y); } private static final long serialVersionUID = 1856835860954L; }
10. Inner classes should not implement Serializable. They use compiler-generated synthetic fields to store references to enclosing instances and to store values of local variables from enclosing scopes. How these fields correspond to the class definition is unspecified, as are the names of anonymous and local classes. Therefore, the default serialized form of an inner class is illdefined. A static member class can, however, implement Serializable.
相关推荐
Item 74: Document all exceptions thrown by each method Item 75: Include failure-capture information in detail messages Item 76: Strive for failure atomicity Item 77: Don’t ignore exceptions 11 ...
rdma-core/irdma: Implement device supported verb APIs
Start Developing iOS Apps (Swift): Implement a Custom Control.webarchive
Oracle 9i: Implement Advanced Queuing 是一个关于Oracle数据库中高级队列技术的教程,主要针对的是Oracle 9i版本。在Oracle数据库中,高级队列(Advanced Queuing,简称AQ)是一个内置的、全面集成的消息队列系统...
《2019年白皮书3:系统级ESD第二部分:有效ESD稳健设计的实现》(Rev 2.0)是一份深入探讨静电放电(ESD)防护在系统层面实施策略的重要文档。这份153页的完整英文电子版详细阐述了ESD在现代电子系统设计中的关键作用...
SELinux_System_Administration_Implement_mandatory_access_control.epub
### Effective C#: Key Insights and Best Practices ...**Item 25: Implement the Event Pattern for Notifications** - **Pattern:** Events allow objects to notify other objects of changes in...
R Data Mining Implement data mining techniques through practical use cases and real world datasets 英文mobi 本资源转载自网络,如有侵权,请联系上传者或csdn删除 查看此书详细信息请在美国亚马逊官网搜索...
• implement transfer learning to solve real-world research problems • Perform complex operations such as image captioning neural style transfer Book Description Transfer learning is a machine ...
淋RPC 在xmlrpc中实现浸入式游戏。 通讯发生在node和python之间。 档案文件 node |--> core |--> drench.js: Implementa a lógica do jogo ...main.py: Implementa um teste do jogo singlepla
* [ ] Step 1: Implement missing features in ram.js * [ ] Step 2: Implement tick() * [ ] Step 3: Implement the HLT instruction handler * [ ] Step 4: Add the LDI instruction * [ ] Step 5: Add the PRN ...
Daozero减少了基于Spring和iBatis的DAO代码。 旧方法是编写代码并显式调用iBatis API,但是Dao-zero在运行时实现DAO接口,并为开发人员自动调用iBatis API。 直接用它替换旧的DAO。
eBook Details: Paperback: 386 pages Publisher: WOW! eBook (February 28, 2019) Language: English ISBN-10: 1789348277 ISBN-13: 978-1789348279
深度强化学习,用于具有多样性代表奖赏的无监督视频摘要。...data.py --input dataset --output dataset/data.h5 分割python create_split.py -d dataset/data.h5 --save-dir dataset --save-name splits --num-splits ...
pdf+epub This book will teach you how to deploy large-scale datasets in deep neural networks with Hadoop for optimal performance. Starting with understanding what deep learning is, and what ...
高清彩版 Implementing Azure Cloud Design Patterns
《Mastering Python for Finance》是一本专注于利用Python语言在金融领域实现先进数学和统计应用的书籍。通过这本书,读者可以理解、设计并实施金融领域内使用的各种尖端技术和方法。本书的作者是James Ma Weiming,...
:Implement of radix-2, radix-3 & radix-5 FFT algorithm 期末考- 快速傅立叶转换的应用 :Implement of radix-2, radix-3 & radix-5 DCT algorithm :Implement of radix-2 DST algorithm :Application of ...