Bean Serializable Interface 的接口让BEAN可以串行化,将其变成一个可保存为以后使用的二进制流。当一个BEAN被系列化到磁盘上或者其他任何地方,其状态被保存起来,其中的属性值也不会改变。在BEAN的规范中,JSP并没有要求BEAN实现Serializable接口。但是,如果您希望自己控制您所创建的组件的serialization进程,或者您想serialize并不是标准组件扩展的组件,您必须了解serialization and deserialization的细节。
有几个原因你会把BEAN冷藏起来以备后用。有些服务器通过将所有的SESSION 数据(包括BEAN)写入磁盘来支持任意长的SESSION生命期,即使服务器停机也不会丢失。当服务器重新启动后,串行化的数据被恢复。同样的理由,在重负载的站点上支持服务器分簇的环境中,许多服务器通过串行化来复制SESSION。如果你的BEAN不支持串行化,服务器就不能正确地保存和传输类。
下面简单介绍一下这个接口:
对象能包含其它的对象,而这其它的对象又可以包含另外的对象。JAVA serialization能够自动的处理嵌套的对象。对于一个对象的简单的域,writeObject()直接将值写入流。而,当遇到一个对象域时,writeObject()被再次调用,如果这个对象内嵌另一个对象,那么,writeObject() 又被调用,直到对象能被直接写入流为止。程序员所需要做的是将对象传入ObjectOutputStream 的writeObject() 方法,剩下的将又系统自动完成。下面的例子创建了一个调用mine对象的PersonalData对象。代码实现的是将一个串和mine 对象输出到一个流,并存入一个文件:
public class PersonalData implements Serializable {
public int id
public int yearOfBirth;
public float yearlySalary;
}
PersonalData mine = new PersonalData(101, 1956, 46500.00);
FileOutputStream outstream = new FileOutputStream("PersonalData.ser");
ObjectOutputStream out = new ObjectOutputStream(outstream);
out.writeObject("My personal data"); //将一个串写入流
out.writeObject(mine); //将这个对象写入流
out.close(); // 清空并关闭流
...
一个FileOutputStream对象被创建且传到一个ObjectOutputStream。当out.writeObject() 被调用,这个串和mine 对象被objects are serializ顺序加入一个存入文件PersonalData.ser的字节对列。
您应该注意上述类是实现的java.io.Serializable接口。因为它并未指定要实现的方法,所以Serializable被称为"tagging interface" ,但是它仅仅"tags"它自己的对象是一个特殊的类型。任一个您希望serialize的对象都应该实现这个接口。这是必须的。否则,用到流技术时将根本不工作。例如,如果您试着去serialize 一个没有实现这个接口的对象,一个 NotSerializableException将产生。
==============================================================================
1、实现Serializable回导致发布的API难以更改,并且使得package-private和private 这两个本来封装的较好的咚咚也不能得到保障了 2、Serializable会为每个类生成一个序列号,生成依据是类名、类实现的接口名、 public和protected方法,所以只要你一不小心改了一个已经publish的API,并且没有自 己定义一个long类型的叫做serialVersionUID的field,哪怕只是添加一个getXX,就会 让你读原来的序列化到文件中的东西读不出来(不知道为什么要把方法名算进去?) 3、不用构造函数用Serializable就可以构造对象,看起来不大合理,这被称为 extralinguistic mechanism,所以当实现Serializable时应该注意维持构造函数中所维 持的那些不变状态 4、增加了发布新版本的类时的测试负担 5、1.4版本后,JavaBeans的持久化采用基于XML的机制,不再需要Serializable 6、设计用来被继承的类时,尽量不实现Serializable,用来被继承的interface也不要 继承Serializable。但是如果父类不实现Serializable接口,子类很难实现它,特别是 对于父类没有可以访问的不含参数的构造函数的时候。所以,一旦你决定不实现 Serializable接口并且类被用来继承的时候记得提供一个无参数的构造函数 7、内部类还是不要实现Serializable好了,除非是static的,(偶也觉得内部类不适合 用来干这类活的) 8、使用一个自定义的序列化方法
看看下面这个保存一个双向链表的例子:
public class StringList implements Serializable
{
?private int size = 0;
?private Entry head = null;
?
?private static class Entry implements Serializable
?{
? String data;
? Entry next;
? Entry previous;
?}
?...//Remainder ommitted
}
这样会导致链表的每个元素以及元素之间的关系(双向链表之间的连接)
都保存下来,更好的方法是提供一个自定义的序列化如下: //String List with a resonable custom serialized form
class StringList implements Serializable
{
? private transient int size = 0;?????? //!transient
? private transient Entry head = null;? //!transient
?
? //no longer serializable!
? private static class Entry
? {
??? String data;
??? Entry next;
??? Entry previous;
? }
?
? //Appends the specified string to the list
? public void add(String s) {/*...*/};
?
? /**
?? * Serialize thisStringListinstance
?? * @author yuchifang
?? * @serialData The size of the list (the number of strings
* it contains) is emitted(int), in the proper sequence
?? */
? private void writeObject(ObjectOutputStream s)
throws IOException
? {
??? s.defaultWriteObject();
??? s.writeInt(size);
??? //Write out all elements in the proper order
??? for (Entry e = head; e != null; e = e.next)
????? s.writeObject(e.data);
? }
?
? private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException
? {
??? int numElements = s.readInt();
???
??? //Read in all elements andd insert them in list
??? for (int i = 0; i < numElements; i++)
????? add((String)s.readObject());
? }
? //...remainder omitted
}
9、不管你选择什么序列化形式,声明一个显式的UID: private static final long serialVersionUID = randomLongValue; 10、不需要序列化的东西使用transient注掉它吧,别什么都留着 11、writeObject/readObject重载以完成更好的序列化 readResolve 与 writeReplace重载以完成更好的维护invariant controllers
只有你要持久化的类采用实现Serializable接口
让对象以数据流的方式传输,而接收该数据流的另一端由可以将他还原成对象。
当然可以由Serializable 完成类的实例持久化,既将对象写到文件中去,当任一需要时再读出来。
本文介绍了Java中BeanSerializableInterface接口的功能及其实现方法,详细解释了如何通过实现Serializable接口来支持对象的串行化过程。同时探讨了串行化过程中的一些注意事项,包括UID的重要性、如何自定义串行化形式等。
1068

被折叠的 条评论
为什么被折叠?



