`
laies
  • 浏览: 240464 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Serializable序列化分析

    博客分类:
  • Java
XML 
阅读更多
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 this StringList instance
    * @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
}
   UID:private static final long serialVersionUID = randomLongValue;
10、不需要序列化的东西使用transient注掉它吧,别什么都留着。
11、writeObject/readObject重载以完成更好的序列化readResolve
   与 writeReplace重载以完成更好的维护invariant controllers

9、不管你选择什么序列化形式,声明一个显式的
分享到:
评论
1 楼 blowfisher 2007-09-19  
很多时候,需要序列化的是值对象 所以很多问题并不是大问题

相关推荐

Global site tag (gtag.js) - Google Analytics