• java序列化与反序列化的使用



    个人博客 地址:http://www.wenhaofan.com/article/20180925214701

    1、什么是序列化和反序列化

    Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化deserialization(反序列化)是一种将这些字节重建成一个对象的过程。


    说通俗一点:

        序列化就是将java中的对象(其中包含对象的信息),以文件的信息保存下来。

        反序列化就是将反序列化的文件的信息读取出来,并转换为一个对象。


    2、什么情况下需要序列化 

        a)当你想把的内存中的对象保存到一个文件中或者数据库中时候;

        b)当你想用套接字在网络上传送对象的时候;

        c)当你想通过RMI传输对象的时候;

    3、如何让对象能够被序列化

        将需要序列化的类实现Serializable接口即可,Serializable接口中没有任何方法,可以理解为一个标记,即表明这个类可以序列化。

    4、序列化和反序列化例子

        序列化:当我们想要序列化一个对象,首先要创建一个OutputStream(例如FileOutputStream、ByteArrayOutputStream等字节流,对象的序列化是基于字节的,不能使用例如Reader以及Writer等基于字符流的层级结构),然后将这些OutputStream封装在一个ObjectOutputStream中。这时候,只需要调用writeObject()方法就可以将对象序列化,也就是会生成一个文件。

        反序列化:当我们需要将一个序列化之后的文件反序列化为一个对象,首先要创建一个InputStream(例如FileOutputStream、ByteArrayOutputStream等字节流,理由同上)获得生成后的序列化文件的流,然后将其封装进 ObjectInputStream。这时候,只需要调用readObject();方法,该方法会返回一个为Object类型的对象,该对象就是通过序列化文本生成的对象。


    代码如下:

    package Serializable;


    import java.io.Serializable;


    /**

     * 测试中需要用来序列化的类

     * @author fwh

     *

     */

    public class Person implements Serializable{

    /**

     * serialVersionUID 

     * java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。

     * 在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,

     * 可以进行反序列化,否则就会出现序列化版本不一致的异常,即是InvalidCastException。

     * 也就是说serialVersionUID可以设定为任意一个类型为long的值,

     * 于此同时接收反序列化的对象的类中的serialVersionUID也必须与序列化的类中的serialVersionUID一致,否则就会出错

     * 

     */

    private static final long serialVersionUID = 1L;


    String name="张三1";



    public String getName() {

    return name;

    }


    public void setName(String name) {

    this.name = name;

    }


    public static long getSerialversionuid() {

    return serialVersionUID;

    }


    @Override

    public String toString() {

    return "Person [name=" + name + "]";

    }

    }


    实现序列化以及反序列化:

        

    package Serializable;


    import java.io.FileInputStream;

    import java.io.FileNotFoundException;

    import java.io.FileOutputStream;

    import java.io.IOException;

    import java.io.ObjectInputStream;

    import java.io.ObjectOutputStream;


    /**

     * 测试序列化以及反序列化

     * @author fwh

     *

     */

    public class  Main{

    public static void main(String[] args) {

    Person person=new Person();

    person.setName("李四");

    //调用本类中执行序列化的方法将person对象序列化

    serializable(person);

    System.out.println("这是序列化之前的对象:"+person);

    //调用本类中执行反序列化的方法获得我们之前序列化的person对象

    FileInputStream fis = null;

    try {

    fis = new FileInputStream("obj.out");

    //因为返回值为Object所以需要强转

    Person p=(Person) deserialization(fis);

    //输出获得到的

    System.out.println("这是通过反序列化得到的对象:"+p);

    } catch (FileNotFoundException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }finally{

    //如果字节流不为空则关闭

    if(fis!=null){

    try {

    fis.close();

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    }

    }

    /**

     * 执行序列化的方法

     */

    public static void serializable(Object obj){

    FileOutputStream fos=null;

    ObjectOutputStream oos = null;

    try {

    //序列化只能使用字节流,对象的序列化是基于字节的,不能使用Reader和Writer等字符流

    fos = new FileOutputStream("obj.out");

    //将输出流封装进使用ObjectOutputStream输出至本地

    oos=new ObjectOutputStream(fos);

        oos.writeObject(obj);

           

    } catch (FileNotFoundException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }finally{

    //如果不为空则刷新执行序列化功能的输出流

    if(oos!=null){

     try {

    oos.flush();

    oos.close();

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

        

    }

           

    }

    /**

     * 执行反序列化的方法

     * @param fis 包含文件信息路径的字节输入流

     * @return 通过反序列化得到的对象

     */

    public static Object deserialization(FileInputStream fis){

            ObjectInputStream ois = null;

            Object obj=null;

    try {

    //反序列化只能使用字节流,对象的序列化是基于字节的,不能使用Reader和Writer等字符流

    ois = new ObjectInputStream(fis);

    obj=ois.readObject();

         

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    } catch (ClassNotFoundException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }finally{

    //如果流不为空,则关闭

    if(ois!=null){

     try {

    ois.close();

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    }

         

    return obj;

    }

    }

  • 相关阅读:
    基于开源SuperSocket实现客户端和服务端通信项目实战
    WinForm基于插件开发实现多项配置存储
    WinForm多线程实现HTTP网络检测工具
    .NET开源分布式日志框架ExceptionLess实战演练(公开版)
    让Windows Server 2008 + IIS 7+ ASP.NET 支持10万并发请求
    .NET基于Eleasticsearch搭建日志系统实战演练
    Spring-Bean配置-使用外部属性文件(转)
    spring事务的隔离级别(透彻理解)
    Spring事务传播机制与隔离级别(转)
    SQL语句200条(转)
  • 原文地址:https://www.cnblogs.com/fanwenhao/p/9703765.html
Copyright © 2020-2023  润新知