java--序列化和反序列化

Posted zghgz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java--序列化和反序列化相关的知识,希望对你有一定的参考价值。

一、序列化

java序列化的过程是把对象转换为字节序列的过程

序列化的两种用途:

  1)把对象的字节序列永久保存大搜硬盘上,通常存放到一个文件中

  2)在网络上传送对象的字节序列

jdk中的序列化API:

java.io.ObjectOutputStream :表示对象输出流,他的writeObject(Object obj)方法可对参数制定的ibj对象进行序列化,把得到的字节序列写到一个目标输出流中。

java.io.ObjectInputStream  :表示对象输入流,他的readObject()方法从一个源输入流中读取字节序列,再把他们反序列化为一个对象,并将其返回。

只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而实现了Serializable接口的类可以采用默认的序列化方式。

二、对象序列化的步骤:

  1、创建一个对象输出流,它可以包装一个其他类型的源输入流,如文件输入流(IO流 装饰者模式)

  2、通过对象输出流的writeObject()方法写对象

对象反序列化额步骤:

  1、新创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流

  2、通过对象输入流的readObject()方法读取对象

 

代码示例:

Person.java  

public class Person implements Serializable {

    private int age;
    private String name;
    private String sex;

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name=‘" + name + ‘‘‘ +
                ", sex=‘" + sex + ‘‘‘ +
                ‘}‘;
    }

    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;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Person(int age, String name, String sex) {
        this.age = age;
        this.name = name;
        this.sex = sex;
    }
}

序列化和反序列化person对象  序列化后的Person.txt文件中乱码 因为序列化的过程是将对象变成二进制存储的

public static void SerializePerson() throws IOException {
        Person person=new Person(15,"xiaoming","nan");
        //ObjectOutputStream 对象输出流,将Person对象存储到Person.txt文件,完成对Person对象的序列化
        ObjectOutputStream oo=new ObjectOutputStream(new FileOutputStream(new File("classpath:Person.txt")));
        oo.writeObject(person);
        System.out.println("serialize complete");
        oo.close();
    }

反序列化的过程:

public static void Deserialize() throws IOException, ClassNotFoundException {
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream("classpath:Person.txt"));
        Person person = (Person) ois.readObject();
        System.out.println(person.toString());
        System.out.println("deserialize complete");
        ois.close();
    }

运行两个过程:

serialize complete
Person{age=15, name=‘xiaoming‘, sex=‘nan‘}
deserialize complete

忽然想起了transient关键字:做了个小改动

为Person类添加一个transient修饰的ext字段 创建person对象时为ext赋值 进行序列化,并且反序列化

public class Person implements Serializable {
    private int age;
    private String name;
    private String sex;
    private transient String ext;

序列化的person.txt文件中没有ext 反序列化的person对象的ext为null

serialize complete
Person{age=15, name=‘xiaoming‘, sex=‘nan‘, ext=‘null‘}
deserialize complete

 

三、serialVersionUUID的作用

serialVersionUUID:序列化版本号,凡是实现Serializable接口的类都有一个表示序列化版本表示的静态变量(没有自动生成 也没有警告)

将Person序列化后再为Person类添加一个属性,再进行反序列化 反序列化失败

 

以上是关于java--序列化和反序列化的主要内容,如果未能解决你的问题,请参考以下文章

java序列化和反序列化

java反序列化引起的内存溢出怎么解决

一文带你全面了解java对象的序列化和反序列化

Java序列化和反序列化——田少嵩

HashMap(key,Object)中的Java Gson序列化和反序列化对象[重复]

Java的序列化和反序列化