1.概念
java中的對(duì)象是存放在內(nèi)存中的谱煤,當(dāng)程序運(yùn)行結(jié)束,內(nèi)存中的對(duì)象也會(huì)隨之被系統(tǒng)回收掉邓了。要想保存對(duì)象就得序列化。序列化后的對(duì)象媳瞪,可以保存在文件或上傳到服務(wù)器骗炉。從文件或網(wǎng)絡(luò)數(shù)據(jù)流中取出對(duì)象,就是反序列化蛇受。
2.Serializable
java.io.Serializable
是一個(gè)空接口句葵,用來(lái)標(biāo)志對(duì)象可以被序列化。這個(gè)標(biāo)志可以被java.io.ObjectOutputStream
和java.io.ObjectInputStream
識(shí)別,將對(duì)象序列化為二進(jìn)制字節(jié)流或從二進(jìn)制字節(jié)流反序列化為對(duì)象實(shí)例乍丈。
3.注意事項(xiàng)
- 若類的成員變量不需要序列化剂碴,可以用
transient
修飾,如:
private transient String name;
- 靜態(tài)變量和
transient
修飾的變量不能被序列化 - 反序列化創(chuàng)建的對(duì)象轻专,與原對(duì)象數(shù)據(jù)基本相同忆矛,但內(nèi)存地址不相同,不是同一個(gè)對(duì)象请垛。需要注意單例對(duì)象的反序列化催训,可能會(huì)在內(nèi)存中產(chǎn)生多個(gè)單例對(duì)象∽谑眨可以使用
readResolve()
方法解決漫拭,這個(gè)方法控制最終反序列化生成的對(duì)象。readResolve()
和writeReplace()
不是Object
和Serializable
的方法混稽,是java默認(rèn)規(guī)范的方法
* <p>Serializable classes that need to designate an alternative object to be
* used when writing an object to the stream should implement this
* special method with the exact signature:
*
* <PRE>
* ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;
* </PRE><p>
*
* This writeReplace method is invoked by serialization if the method
* exists and it would be accessible from a method defined within the
* class of the object being serialized. Thus, the method can have private,
* protected and package-private access. Subclass access to this method
* follows java accessibility rules. <p>
*
* Classes that need to designate a replacement when an instance of it
* is read from the stream should implement this special method with the
* exact signature.
*
* <PRE>
* ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
* </PRE><p>
- 如果想對(duì)某些成員變量做特殊處理采驻,比如取值范圍校驗(yàn)、加密數(shù)據(jù)荚坞,可以通過(guò)
writeObject()
和readObject()
進(jìn)行挑宠。同樣的這兩個(gè)方法也不是Object
和Serializable
的方法
* Classes that require special handling during the serialization and
* deserialization process must implement special methods with these exact
* signatures:
*
* <PRE>
* private void writeObject(java.io.ObjectOutputStream out)
* throws IOException
* private void readObject(java.io.ObjectInputStream in)
* throws IOException, ClassNotFoundException;
* private void readObjectNoData()
* throws ObjectStreamException;
* </PRE>
*
* <p>The writeObject method is responsible for writing the state of the
* object for its particular class so that the corresponding
* readObject method can restore it. The default mechanism for saving
* the Object's fields can be invoked by calling
* out.defaultWriteObject. The method does not need to concern
* itself with the state belonging to its superclasses or subclasses.
* State is saved by writing the individual fields to the
* ObjectOutputStream using the writeObject method or by using the
* methods for primitive data types supported by DataOutput.
*
* <p>The readObject method is responsible for reading from the stream and
* restoring the classes fields. It may call in.defaultReadObject to invoke
* the default mechanism for restoring the object's non-static and
* non-transient fields. The defaultReadObject method uses information in
* the stream to assign the fields of the object saved in the stream with the
* correspondingly named fields in the current object. This handles the case
* when the class has evolved to add new fields. The method does not need to
* concern itself with the state belonging to its superclasses or subclasses.
* State is saved by writing the individual fields to the
* ObjectOutputStream using the writeObject method or by using the
* methods for primitive data types supported by DataOutput.
*
* <p>The readObjectNoData method is responsible for initializing the state of
* the object for its particular class in the event that the serialization
* stream does not list the given class as a superclass of the object being
* deserialized. This may occur in cases where the receiving party uses a
* different version of the deserialized instance's class than the sending
* party, and the receiver's version extends classes that are not extended by
* the sender's version. This may also occur if the serialization stream has
* been tampered; hence, readObjectNoData is useful for initializing
* deserialized objects properly despite a "hostile" or incomplete source
* stream.
-
private static final long serialVersionUID = 5316419709815709313L;
版本id可以直接指定,如果不設(shè)置颓影,會(huì)根據(jù)類的信息動(dòng)態(tài)生成。