序列化Serializable的学习笔记

来源:互联网 发布:淘宝店铺三个月 编辑:程序博客网 时间:2024/06/13 12:41
在web应用中,需要将对象等序列化成流,以方便在服务器等之间传输,比如将对象序列化后存入文件中。序列化旧手机将对象转换成一个流,反序列化就是将转换后的流再在堆里重新构建成对象。

       如何将对象序列化呢?

       通过使用ObjectOutputStream来将内存中的对象进行序列化,通过ObjectInputStream来将InputStream反序列化为对象。

        通常我们用它们装饰FileOutputStream/FileInputStream,以通过文件将序列化后的对象进行存储,或者从文件中将对象反序列化。例如:     

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.io.Serializable;

import java.util.HashMap;

import java.util.Map;

  

public class Persistence implements Serializable{

 

    private static Map variables = null;

    private static String tmpFile = "D:/tmpFile.bin";

 

    static {

        try {

                if (new File(tmpFile).exists()) {

                    FileInputStream fis = new FileInputStream(tmpFile);

                    ObjectInputStream in = new ObjectInputStream(fis);

                   //从文件中将序列化后的对象读出,并反序列化后赋值给一个变量,这里

                  //反序列化后的对象时Object类型,需要向下转换为相应类型

                    variables = (Map)in.readObject();

                    in.close();

                }

                if (variables == null) {

                    variables = new HashMap();

                }

        } catch (Exception e) {

            e.printStackTrace();

        } 

    }

 

    public static void setVariables(String name,Serializable object) {

        if (variables != null) {

            variables.put(name, object);

        }

        FileOutputStream fos;

        try {

            fos = new FileOutputStream(tmpFile);

            ObjectOutputStream out = new ObjectOutputStream(fos);

           //将对象序列化后,存入fos所指向的文件中

            out.writeObject(variables);

           //清空缓存

            out.flush();

            out.close();

        } catch (Exception e) {

            e.printStackTrace();

       }

    }

    public static Serializable getVariables(String name) {

        if (variables != null) {

            return (Serializable)variables.get(name);

        }

        return null;

    } 

}

       即:将FileOutputStream的输出流用ObjectOutputStream来包装,用writeObject(variables)来将对象序列化后,通过FileOutputStream来将序列化后的对象保存在文件中;ObjectInputStream包装输入流FileInputStream,将输入流中的内容用readObject()方法来反序列化为对象。

      注意:

      1、要序列化一个对象,则该对象及其属性都必须是实现了Serializable接口的,否则会报异常

      2、要序列化一个对象,但又不希望他的某些属性被序列化,可以在这些属性的前面用transient

           修饰,这样被transient修饰的属性就不会被序列化了;

      3、当反序列化一个对象的时候,其构造方法不会被调用;

      4、对象->文件->对象(即序列化,反序列化过程),在这个过程汇中,如果对象所属的类发生变化,将无法成功反序列化;

      5、当对象被序列化之后,改变了对象所属的类,又希望对象可以被反序列化

           ——在JDK1.5以后,可以通过在类中定义serialVersionUID来解决问题

           ——在JDK1.4以前,不可以

          serialVersionUID 实际上就是个版本号,可以通过IDE自动生成这个版本号,也可以自己手动输入一个,它是static final long类型的。通过定义serialVersionUID 就可以解决上述问题。只要保证序列化后的文件中的serialVersionUID和类中的serialVersionUID 是一样的,即使该类被改变了,对象同样可以反序列化,但如果二者不一样,即使类没有被改变,对象也不能反序列化。所以是否能够反序列化就要看serialVersionUID 是否相同。
原创粉丝点击