zoukankan      html  css  js  c++  java
  • 47、序列化和反序列化

    在工作中有可能遇到多台机器远程通信的情况,如果要将机器A中的某个java对象传输到机器B上面,需要将这个java对象转换为字节序列然后进行传输。将对象转换为字节序列的过程叫做序列化,反之叫做反序列化。

    一个对象如果支持序列化,需要实现Serializable的接口,这个接口中没有任何方法,实现该接口后,JVM会给这个对象做特殊待遇

    将java对象保存到硬盘里面

    使用序列化还可以将一个对象保存到硬盘中,然后再通过反序列化将该对象读取到内存里面。

    创建一个Student类,实现Serializable接口

    package com.monkey1024.serializable;
    
    import java.io.Serializable;
    
    public class Student implements Serializable {
    
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }

    使用ObjectOutputStream将Student对象写出到硬盘中

    package com.monkey1024.serializable;
    
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    
    /**
     * 将Student对象序列化到硬盘中
     *
     */
    public class ObjectOutput {
    
        public static void main(String[] args) {
            Student s = new Student();
            s.setName("张三");
    
            // 创建输出流(序列化流) 
            try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("zhangsan"));) {
                //将对象写出到硬盘中
                oos.writeObject(s);
                oos.flush();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    使用ObjectInputStream将硬盘中的对象读取到内存中

    package com.monkey1024.serializable;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    
    /**
     * 从硬盘中读取Student对象
     *
     */
    public class ObjectInput {
    
        public static void main(String[] args) {
            try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("zhangsan"));) {
                Student s = (Student)ois.readObject();
                System.out.println(s.getName());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    序列化版本号

    在一个类实现Serializable接口后,系统会给每个对象一个序列化版本号,当这个类的源码被修改后,系统会重新分配一个新的序列化版本号,这样做的好处就是保证序列化和反序列化的对象内容一致。例如将一个对象序列化到硬盘之后,修改这个对象所对应类的源码,在进行反序列化是就会报出InvalidClassException异常。如果手动编写序列化版本号之后,就不会出现这个异常了。

    package com.monkey1024.serializable;
    
    import java.io.Serializable;
    
    public class Student implements Serializable {
    
        /**
         * 自动生成序列化版本号
         */
        private static final long serialVersionUID = -716323668524282676L;
    
        private String name;
        private int age;
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }

    transient关键字

    如果不希望将Student类中的age属性序列化,可以使用transient声明该属性,在序列化时将忽略这个属性。

    package com.monkey1024.serializable;
    
    import java.io.Serializable;
    
    public class Student implements Serializable {
    
        /**
         * 自动生成序列化版本号
         */
        private static final long serialVersionUID = -716323668524282676L;
    
        private String name;
    
        //age不序列化
        transient private int age;
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
  • 相关阅读:
    C# 数据库访问
    ArcGIS API For Silverlight使用在线地图的多种方法总结
    Google Map Api 谷歌地图接口整理
    定义函数up(ch),如字符变量ch是小写字母就转换成大写字母并通过up返回,否则字符ch不改变。要求在短小而完全的程序中显示这个程序是怎样被调用的-简单
    编写一个求方程ax^2+bx+c=0的根的程序,用3个函数分别求当b^2-4ac大于零、等于零和小于零时的方程的根。要求从主函数输入a、b、c的值并输出结果-简单
    已知一个string的对象str的内容为“we are here!”, 使用多种方法输出字符“h”-简单
    使用多种方法编写将两个字符串连接在一起的程序-简单
    c++简单函数应用
    编写一个完整的程序,它读入15个float值,用指针把它们存放在一个存储快里,然后输出这些值的和以及最小值
    编写一个为int型变量分配100个整型量空间的程序-简单
  • 原文地址:https://www.cnblogs.com/zhuifeng-mayi/p/10145545.html
Copyright © 2011-2022 走看看