首页 > 代码库 > 序列化,反序列话实例

序列化,反序列话实例

public class foo implements Serializable{
    private int width;
    private int height;
    public int getWidth() {
        return width;
    }
    public void setWidth(int width) {
        this.width = width;
    }
    public int getHeight() {
        return height;
    }
    public void setHeight(int height) {
        this.height = height;
    }
    
}


public class test_serialize extends TestCase {

//序列化,fileoutputstream 存储路径文件,如果是相对路径,那么存储在项目根目录下,如果是绝对路径,存储在绝对路径下面
    public void tests() throws IOException{
        foo a = new foo();
        a.setHeight(200);
        a.setWidth(300);
        foo b = new foo();
        b.setHeight(300);
        b.setWidth(400);
        try{
        FileOutputStream fs=new FileOutputStream("d:/foo.ser");
        ObjectOutputStream os = new ObjectOutputStream(fs);
        os.writeObject(a);
        os.writeObject(b);
        os.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }

//反序列化
    public void testgets() throws IOException, ClassNotFoundException{
        try {
            FileInputStream fs = new FileInputStream("d:/foo.ser");
            ObjectInputStream ois = new ObjectInputStream(fs);
            foo a=(foo)ois.readObject();
            foo b=(foo)ois.readObject();
            System.out.println(a.getHeight());
            System.out.println(b.getHeight());
            
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}



相关注意事项
    a)序列化时,只对对象的状态进行保存,而不管对象的方法;
    b)当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;
    c)当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;
    d)并非所有的对象都可以序列化,,至于为什么不可以,有很多原因了,比如:
        1.安全方面的原因,比如一个对象拥有private,public等field,对于一个要传输的对象,比如写到文件,或者进行rmi传输  等等,在序列化进行传输的过程中,这个对象的private等域是不受保护的。
       2. 资源分配方面的原因,比如socket,thread类,如果可以序列化,进行传输或者保存,也无法对他们进行重新的资源分  配,而且,也是没有必要这样实现。 


默认的 serialization 对 类的结构有要求,一般将来版本升级了导致服务端和客户版本不一样,或者你用新版本读取一个以前旧版本写入磁盘的序列化的对象的话,需要这两个版本是兼容 的,达到这个要求至少包括下面这个字段,并且新旧两个版本的类中它的值应该是一样的,其它特殊情况规范也有办法做到,比如你的结构变了,以前 name / phone 都是 A 的字段,后来新版本创建了一个内部类叫 Contact name phone
并到这两个字段移到内部类 Contact 中去了的话,Java 也有办法在新版本中提供自定义 readObject/writeObject 这个过程来确保兼容旧版本。

private static final long serialVersionUID; //
在一个类的多个版本中要相同的值,对于不它的类中,它们的值不要求唯一。
http://java.sun.com/developer/technicalArticles/Programming/serialization/
 

serialVersionUID作用:序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。 有两种生成方式: 一个是默认的1L,比如:private static final long se...

serialVersionUID作用:
序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。

有两种生成方式:

一个是默认的1L,比如:
private static final long serialVersionUID = 1L;
一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:

 
private static final long serialVersionUID = xxxxL;
当你一个类实现了Serializable接口,如果没有定义serialVersionUIDEclipse会提供这个

提示功能告诉你去定义 。在Eclipse中点击类中warning的图标一下,Eclipse就会

自动给定两种生成的方式。如果不想定义它,在Eclipse的设置中也

可以把它关掉的,设置如下:

 
Window ==> Preferences ==> Java ==> Compiler ==> Error/Warnings ==>
Potential programming problems
Serializable class without serialVersionUIDwarning改成ignore即可。

如果你没有考虑到兼容性问题时,就把它关掉,不过有这个功能是好的,只要任何类别实现了Serializable这个接口的话,如果没有加入serialVersionUIDEclipse都会给你warning提示,这个serialVersionUID为了让该类别Serializable向后兼容。

如果你的类Serialized存到硬盘上面后,可是后来你却更改了类别的field(增加或减少或改名),当你Deserialize时,就会出现Exception的,这样就会造成不兼容性的问题。

但当serialVersionUID相同时,它就会将不一样的fieldtype的预设值Deserialize,可避开不兼容性问题。


序列化,反序列话实例