- 浏览: 794125 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (651)
- Java (39)
- Java 初学者小问题 (66)
- 设计模式 (7)
- 项目管理 (3)
- 数据库 (1)
- 算法 (2)
- Java practices (6)
- Effective Java2读书笔记 (78)
- Linux (2)
- programming ruby 读书笔记 (5)
- Core Java Ninth Edition Volume I 读书笔记 (15)
- Pro Git 读书笔记 (12)
- Git (3)
- Maven in Action 读书笔记 (20)
- Web (12)
- 非技术类书籍 (11)
- 电影 (40)
- Web Cache (1)
- jquery (0)
- 历史 (4)
- Dive Into HTML5 读书笔记 (13)
- 三国演义小学毕业考 (79)
- 高效能人士的7个习惯 读书笔记 (12)
- Java Performance 读书笔记 (3)
- Protocol Buffer 学习笔记 (6)
- Mongo DB 学习笔记 (7)
- Morphia 学习笔记 (7)
- Algorithms -- Princeton 学习笔记 (13)
- String研究 (10)
- Hadoop: The Definitive Guide 读书笔记 (3)
- Java与模式读书笔记 (5)
- Date研究 (3)
- The Roman Empire 听课笔记 (4)
- Algorithms -- Standford 学习笔记 (16)
- Core Java Ninth Edition Volume II 读书笔记 (9)
- Thinking in Java 4th Edition 读书笔记 (21)
- Node : Up and Running 学习笔记 (5)
- Eloquent Javascript (8)
- Smashing Node.js 读书笔记 (1)
- Algorithms II -- Standford 学习笔记 (19)
- Algorithm II -- Princeton 学习笔记 (14)
- 网络安全 (2)
- Javascript (4)
- 正则表达式 (1)
- JAVA 7/8 (15)
- JVM (10)
- NodeJS (1)
- 鸟哥的linux私房菜读书笔记 (14)
- Web Service (1)
- The art of programming (9)
- Introduction to Algorithm 读书笔记 (4)
- Java 源码阅读 (0)
- Spring in Action 读书笔记 (2)
- Java Network Programming 读书笔记 (2)
最新评论
-
心存高远:
谢谢作者分享,刚好看到这里不太明白,现在茅塞顿开。不过runt ...
关于 Maven的传递依赖的理解 -
sxlkk:
851228082 写道甚至在某次技术会议现场遇到《Maven ...
关于 Maven的传递依赖的理解 -
851228082:
851228082 写道a----compile----b-- ...
第五章 坐标和依赖 -
851228082:
a----compile----b-----provided- ...
第五章 坐标和依赖 -
851228082:
甚至在某次技术会议现场遇到《Maven in action》的 ...
关于 Maven的传递依赖的理解
Do not implement Serializable lightly, since it restricts future flexibility, and publicly exposes class implementation details which are usually private. As well, implementing Serializable correctly is not trivial.
The serialVersionUID is a universal version identifier for a Serializable class. Deserialization uses this number to ensure that a loaded class corresponds exactly to a serialized object. If no match is found, then an InvalidClassException is thrown.
Guidelines for serialVersionUID :
- always include it as a field, for example: "private static final long serialVersionUID = 7526472295622776147L; " include this field even in the first version of the class, as a reminder of its importance
- do not change the value of this field in future versions, unless you are knowingly making changes to the class which will render it incompatible with old serialized objects
- new versions of Serializable classes may or may not be able to read old serialized objects; it depends upon the nature of the change; provide a pointer to Sun's guidelines for what constitutes a compatible change, as a convenience to future maintainers
In Windows, generate serialVersionUID using the JDK's graphical tool like so :
- use Control Panel | System | Environment to set the classpath to the correct directory
- run serialver -show from the command line
- point the tool to the class file including the package, for example, finance.stock.Account - without the .class
- (here are the serialver docs for both Win and Unix)
readObject and writeObject :
- readObject implementations always start by calling default methods
- deserialization must be treated as any constructor : validate the object state at the end of deserializing - this implies that readObject should almost always be implemented in Serializable classes, such that this validation is performed.
- deserialization must be treated as any constructor : if constructors make defensive copies for mutable object fields, so must readObject
- when serializing a Collection, store the number of objects in the Collection as well, and use this number to read them back in upon deserialization; avoid tricks using null
Other points :
- use javadoc's @serial tag to denote Serializable fields
- the .ser extension is conventionally used for files representing serialized objects
- no static or transient fields undergo default serialization
- extendable classes should not be Serializable, unless necessary
- inner classes should rarely, if ever, implement Serializable
- container classes should usually follow the style of Hashtable, which implements Serializable by storing keys and values, as opposed to a large hash table data structure
Example
import java.io.Serializable; import java.text.StringCharacterIterator; import java.util.*; import java.io.*; public final class SavingsAccount implements Serializable { /** * This constructor requires all fields to be passed as parameters. * * @param aFirstName contains only letters, spaces, and apostrophes. * @param aLastName contains only letters, spaces, and apostrophes. * @param aAccountNumber is non-negative. * @param aDateOpened has a non-negative number of milliseconds. */ public SavingsAccount ( String aFirstName, String aLastName, int aAccountNumber, Date aDateOpened ){ super(); setFirstName(aFirstName); setLastName(aLastName); setAccountNumber(aAccountNumber); //make a defensive copy of the mutable Date passed to the constructor setDateOpened( new Date(aDateOpened.getTime()) ); //there is no need here to call validateState. } public SavingsAccount () { this ("FirstName", "LastName", 0, new Date(System.currentTimeMillis())); } public final String getFirstName() { return fFirstName; } public final String getLastName(){ return fLastName; } public final int getAccountNumber() { return fAccountNumber; } /** * Returns a defensive copy of the field. * The caller may change the state of the returned object in any way, * without affecting the internals of this class. */ public final Date getDateOpened() { return new Date(fDateOpened.getTime()); } /** * Names must contain only letters, spaces, and apostrophes. * Validate before setting field to new value. * * @throws IllegalArgumentException if the new value is not acceptable. */ public final void setFirstName( String aNewFirstName ) { validateName(aNewFirstName); fFirstName = aNewFirstName; } /** * Names must contain only letters, spaces, and apostrophes. * Validate before setting field to new value. * * @throws IllegalArgumentException if the new value is not acceptable. */ public final void setLastName ( String aNewLastName ) { validateName(aNewLastName); fLastName = aNewLastName; } /** * Validate before setting field to new value. * * @throws IllegalArgumentException if the new value is not acceptable. */ public final void setAccountNumber( int aNewAccountNumber ) { validateAccountNumber(aNewAccountNumber); fAccountNumber = aNewAccountNumber; } public final void setDateOpened( Date aNewDate ){ //make a defensive copy of the mutable date object Date newDate = new Date( aNewDate.getTime()); validateDateOpened( newDate ); fDateOpened = newDate; } // PRIVATE // /** * The client's first name. * @serial */ private String fFirstName; /** * The client's last name. * @serial */ private String fLastName; /** * The client's account number. * @serial */ private int fAccountNumber; /** * The date the account was opened. * @serial */ private Date fDateOpened; /** * Determines if a de-serialized file is compatible with this class. * * Maintainers must change this value if and only if the new version * of this class is not compatible with old versions. See Sun docs * for <a href=http://java.sun.com/products/jdk/1.1/docs/guide * /serialization/spec/version.doc.html> details. </a> * * Not necessary to include in first version of the class, but * included here as a reminder of its importance. */ private static final long serialVersionUID = 7526471155622776147L; /** * Verify that all fields of this object take permissible values; that is, * this method defines the class invariant. * * In this style of implementation, both the entire state of the object * and its individual fields can be validated without repeating or * duplicating code. * Each condition is defined in one place. Checks on the entire * object are performed at the end of object construction, and at * the end of de-serialization. Checks on individual fields are * performed at the start of the corresponding setXXX method. * As well, this style replaces the if's and throwing * of exceptions at the start of a setXXX, with a simple call to validateXXX. * Validation is separated from the regular path of execution, * which leads to improved legibility. * * @throws IllegalArgumentException if any field takes an unpermitted value. */ private void validateState() { validateAccountNumber(fAccountNumber); validateName(fFirstName); validateName(fLastName); validateDateOpened(fDateOpened); } /** * Ensure names contain only letters, spaces, and apostrophes. * * @throws IllegalArgumentException if field takes an unpermitted value. */ private void validateName(String aName){ boolean nameHasContent = (aName != null) && (!aName.equals("")); if (!nameHasContent){ throw new IllegalArgumentException("Names must be non-null and non-empty."); } StringCharacterIterator iterator = new StringCharacterIterator(aName); char character = iterator.current(); while (character != StringCharacterIterator.DONE ){ boolean isValidChar = (Character.isLetter(character) || Character.isSpaceChar(character) || character =='\'' ); if ( isValidChar ) { //do nothing } else { String message = "Names can contain only letters, spaces, and apostrophes."; throw new IllegalArgumentException(message); } character = iterator.next(); } } /** * AccountNumber must be non-negative. * @throws IllegalArgumentException if field takes an unpermitted value. */ private void validateAccountNumber(int aAccountNumber){ if (aAccountNumber < 0) { String message = "Account Number must be greater than or equal to 0."; throw new IllegalArgumentException(message); } } /** * DateOpened must be after 1970. * @throws IllegalArgumentException if field takes an unpermitted value. */ private void validateDateOpened( Date aDateOpened ) { if( aDateOpened.getTime()<0 ) { throw new IllegalArgumentException("Date Opened must be after 1970."); } } /** * Always treat de-serialization as a full-blown constructor, by * validating the final state of the de-serialized object. */ private void readObject( ObjectInputStream aInputStream ) throws ClassNotFoundException, IOException { //always perform the default de-serialization first aInputStream.defaultReadObject(); //make defensive copy of the mutable Date field fDateOpened = new Date( fDateOpened.getTime() ); //ensure that object state has not been corrupted or tampered with maliciously validateState(); } /** * This is the default implementation of writeObject. * Customise if necessary. */ private void writeObject( ObjectOutputStream aOutputStream ) throws IOException { //perform the default serialization for all non-transient, non-static fields aOutputStream.defaultWriteObject(); } }
This article originates from http://www.javapractices.com/topic/TopicAction.do?Id=45
发表评论
-
Avoid clone
2010-10-31 12:07 990Avoid implementing clone. c ... -
Immutable objects
2010-10-21 22:46 1016Immutable objects are simply ob ... -
Validate state with class invariants
2010-10-21 22:24 1373Class invariants are methods wh ... -
Lazy initialization
2010-10-21 12:03 1102Lazy initialization is a perfor ... -
Copy constructors
2010-10-20 23:57 903Copy constructors : provide ...
相关推荐
implementing Serializable 接口可以确保对象可以被正确地序列化和反序列化。 使用场景 对象到 byte 数组的转换非常有用,例如: * 数据存储:将对象转换为 byte 数组可以将其存储在数据库或文件中。 * 网络传输...
Haeinsa uses two-phase locking and optimistic concurrency control for implementing transaction. The isolation level of transaction is serializable. Features Please see Haeinsa Wiki for further ...
All arrays and lists implementing Microsoft's IList interface are drawn by our powerful list drawer; drag & drop, insert and delete individual items, multi-dim arrays [NEW], tables [NEW], cross-list ...
- **Custom Equality:** Implementing `IEquatable<T>` to define custom equality logic. **Item 7: Understand the Pitfalls of GetHashCode()** - **Issues:** Incorrect implementation can lead to poor ...
Item 14: Consider implementing Comparable 4 Classes and Interfaces Item 15: Minimize the accessibility of classes and members Item 16: In public classes, use accessor methods, not public fields Item ...
例如,我们可以创建一个抽象基类`BaseClass`,包含一些通用方法,然后有一个`ChildClass`继承自`BaseClass`,并可能实现一个或多个接口,如`Actionable`或`Serializable`。这样,`ChildClass`就可以利用`BaseClass`...
Lesson 5: Concepts – Formulating and Implementing Resolution 81 Module 4: Troubleshooting Locking and Blocking Overview At the end of this module, you will be able to: Discuss how ...
- **1.3.17 可序列化对象(Serializable Objects)**:描述了可序列化对象的特点及其应用场景。 - **1.3.18 折旧 Slice 定义(Deprecating Slice Definitions)**:介绍了如何对不再使用的Slice定义进行折旧处理。 ...
Action, LocaleProvider, TextProvider, Validateable, ValidationAware, Serializable 直接已知子类: DefaultActionSupport ------------------------------------------------------------------------------...