• 技术文章 >Java >java教程

    JAVA之序列化

    黄舟黄舟2017-02-24 09:44:30原创915

    1、问题:

      如果想往一个文件中写入一个对象,发现字节流,字符流都不能满足要求, 如何向一个文件中写入对象?
    使用字节字符流,都必须要将对象转为字节/字符,再写到文件中,可以字节字符流没有将对象转为字节的方法,这要如何做?

    2、序列化与反序列化

    Java序列化:将对象转为字节的过程,这正好符合我的需求。
    Java反序列化:将字节恢复为对象的过程
    这满足我们想文件中写对象,和读取对象

    3、序列化和反序列化的使用场景

    5、如何实现序列化和反序列化

    5.1 、实现Serializable接口

      Serializable接口没有任何方法,只是提供一个标识 , 用来告诉java机制该类可以被序列化;
       如果没有创建这个标识,java机制将会自动的创建一个,SerialVersionUID是根据类名, 接口名,成员方法及属性等来生成一个64位哈希字段

    package com.chb.test;import java.io.Serializable;public class Student implements Serializable{
        //序列化标识
        private static final long serialVersionUID = 1L;    
        private String name;    
        private int age;    
        private String sex;    
        public Student() {
        }    
        public Student(String name, int age, String sex) {        
        super();        
        this.name = name;        
        this.age = age;        
        this.sex = sex;
        }    
        @Override
        public String toString() {        
        return "Student{"
                    +"姓名:"+this.name
                    +"性别:"+this.sex
                    +"年龄"+this.age
                    + "}";
        }    
        /**setter getter 省略。。。*/    
        }

    5.2、ObjectOutputStream与ObjectInputStream

      Serializalable接口只是提供一个表示,将对象转为二进制序列,和二进制序列恢复成对象是由ObjectOutputStream和OjbectInputStream提供的两个方法:writeObject()和readObject()

    public static void write(Student s1) throws Exception {
            FileOutputStream fos = new FileOutputStream(filename);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(s1);
            oos.close();
    }
    public static Student read() throws Exception {
            FileInputStream fis = new FileInputStream(filename);
            ObjectInputStream ois = new ObjectInputStream(fis);
            Student stu = new Student();        //使用readeObject()进行反序列化
            stu= (Student) ois.readObject();
            ois.close();        return stu;
    }

    6、transient

    在某种场合,我们对某些敏感字段不要进行序列化,或者类的引用类型的成员不能够进行序列化, 这是我们需要使用transient来修饰这些成员, 以避免它们被序列化。如:银行账户对象,不希望对账户金额进行序列化。
    修改上面的Student类,将sex属性使用transient修饰

    transient private String sex;

    再进行序列化

    Student s1 = new Student("roase",19, "女");
    write(s1);

    反序列化, 读取的对象发现:sex为null,说明被transient修饰的属性不会被序列化。
    这里写图片描述

    6.1 defaultWriteObject和defaultReadObject()

    对于上面的被transient的成员age, 如果我们想让它能够在此序列化和反序列化,要如何做:

        private void writeObject(ObjectOutputStream out) throws Exception{        
        out.defaultWriteObject();        
        out.writeInt(age);
        }    
        private void  readObject(ObjectInputStream in) throws Exception {        
        in.defaultReadObject();
            age=in.readInt();
        }

    在writeObject()方法中会先调用ObjectOutputStream中的defaultWriteObject()方法,该方法会执行默认的序列化机制,此时会忽略掉age字段。然后再调用writeInt()方法显示地将age字段写入到ObjectOutputStream中。readObject()的作用则是针对对象的读取,其原理与writeObject()方法相同。再次执行read()应用程序,则又会有如下输出:

    这里写图片描述

    1、问题:

      如果想往一个文件中写入一个对象,发现字节流,字符流都不能满足要求, 如何向一个文件中写入对象?
    使用字节字符流,都必须要将对象转为字节/字符,再写到文件中,可以字节字符流没有将对象转为字节的方法,这要如何做?

    2、序列化与反序列化

    Java序列化:将对象转为字节的过程,这正好符合我的需求。
    Java反序列化:将字节恢复为对象的过程
    这满足我们想文件中写对象,和读取对象

    3、序列化和反序列化的使用场景

    5、如何实现序列化和反序列化

    5.1 、实现Serializable接口

      Serializable接口没有任何方法,只是提供一个标识 , 用来告诉java机制该类可以被序列化;
       如果没有创建这个标识,java机制将会自动的创建一个,SerialVersionUID是根据类名, 接口名,成员方法及属性等来生成一个64位哈希字段

    package com.chb.test;import java.io.Serializable;public class Student implements Serializable{
        //序列化标识
        private static final long serialVersionUID = 1L;    
        private String name;    
        private int age;    
        private String sex;    
        public Student() {
        }    
        public Student(String name, int age, String sex) {        
        super();        
        this.name = name;        
        this.age = age;        
        this.sex = sex;
        }    
        @Override
        public String toString() {        
        return "Student{"
                    +"姓名:"+this.name
                    +"性别:"+this.sex
                    +"年龄"+this.age
                    + "}";
        }    
        /**setter getter 省略。。。*/    }

    5.2、ObjectOutputStream与ObjectInputStream

      Serializalable接口只是提供一个表示,将对象转为二进制序列,和二进制序列恢复成对象是由ObjectOutputStream和OjbectInputStream提供的两个方法:writeObject()和readObject()

    public static void write(Student s1) throws Exception {
            FileOutputStream fos = new FileOutputStream(filename);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(s1);
            oos.close();
    }
    public static Student read() throws Exception {
            FileInputStream fis = new FileInputStream(filename);
            ObjectInputStream ois = new ObjectInputStream(fis);
            Student stu = new Student();        //使用readeObject()进行反序列化
            stu= (Student) ois.readObject();
            ois.close();        return stu;
    }

    6、transient

    在某种场合,我们对某些敏感字段不要进行序列化,或者类的引用类型的成员不能够进行序列化, 这是我们需要使用transient来修饰这些成员, 以避免它们被序列化。如:银行账户对象,不希望对账户金额进行序列化。
    修改上面的Student类,将sex属性使用transient修饰

    transient private String sex;

    再进行序列化

    Student s1 = new Student("roase",19, "女");
    write(s1);

    反序列化, 读取的对象发现:sex为null,说明被transient修饰的属性不会被序列化。
    这里写图片描述

    6.1 defaultWriteObject和defaultReadObject()

    对于上面的被transient的成员age, 如果我们想让它能够在此序列化和反序列化,要如何做:

        private void writeObject(ObjectOutputStream out) throws Exception{        
        out.defaultWriteObject();        
        out.writeInt(age);
        }    
        private void  readObject(ObjectInputStream in) throws Exception {        
        in.defaultReadObject();
            age=in.readInt();
        }

    在writeObject()方法中会先调用ObjectOutputStream中的defaultWriteObject()方法,该方法会执行默认的序列化机制,此时会忽略掉age字段。然后再调用writeInt()方法显示地将age字段写入到ObjectOutputStream中。readObject()的作用则是针对对象的读取,其原理与writeObject()方法相同。再次执行read()应用程序,则又会有如下输出:

    这里写图片描述

    以上就是JAVA之序列化的内容,更多相关内容请关注PHP中文网(m.sbmmt.com)!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:JAVA,序列化
    上一篇:Java 8 API 设计经验浅析 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • Java数据结构之单链表与OJ题• 一起来分析java设计模式之单例• 详细介绍Java正则表达式之单字符匹配和预定义字符• 一文搞懂Java线程池实现原理• Java总结分享之反射、枚举、Lambda表达式
    1/1

    PHP中文网