码迷,mamicode.com
首页 > 编程语言 > 详细

java_序列化

时间:2019-01-07 17:33:59      阅读:220      评论:0      收藏:0      [点我收藏+]

标签:增加   override   文本   catch   targe   int   app   ati   rgs   

1.概念

序列化:将对象转化为字节序列的过程

反序列化:将字节序列转化为对象的过程

用途:

A:将对象转化为字节序列保存在硬盘上,如文件中,如文本中的例子就是将person对象序列化成字节序列,存在person.txt文件中

B:网络传输中一般都是以对象序列化的形式存在,在网络的发送/接收两端进行对象的序列化/反序列化

输入/输出的使用:

一般都是针对内存而言,内存--硬盘--》outputStream     从硬盘--内存--》inputStream

具体使用要根据场景来确定

2.example

2.1 无显式的指定UID,采用编译系统自动生成的

Object:

package com.java.baseinfo.knowledge.code.serializable;

import java.io.Serializable;

public class Person implements Serializable {

    private int age;

    private String name;

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

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("Person{");
        sb.append("age=").append(age);
        sb.append(", name=‘").append(name).append(‘\‘‘);
        sb.append(", sex=‘").append(sex).append(‘\‘‘);
        sb.append(‘}‘);
        return sb.toString();
    }
}

 object  uid

package com.java.baseinfo.knowledge.code.serializable;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class TestObjSerializeAndDeserialize {

    public static void main(String[] args) {
        // 序列化
        SerializablePerson();
        // 反序列化
        //Deserialization();
    }

    private static void SerializablePerson() {
        Person person = new Person();
        person.setAge(10);
        person.setName("测试");
        person.setSex("女");

        String path = "src/test/resources/person.txt";

        try {
            FileOutputStream fileOutputStream = new FileOutputStream(new File(path));

            ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);

            objectOutputStream.writeObject(person);

            System.out.println("序列化成功");
            fileOutputStream.close();
            objectOutputStream.close();

        } catch (FileNotFoundException e) {
            System.out.printf("FileNotFoundException====>" + e);
        } catch (IOException e) {
            System.out.printf("IOException====>" + e);
        }
    }

    private static Person Deserialization() {

        try {
            FileInputStream fileInputStream = new FileInputStream(new File("src/test/resources/person.txt"));

            ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);

            Person person = (Person) objectInputStream.readObject();

            System.out.printf("Deserialization.person===>"+person);

        } catch (FileNotFoundException e) {
            System.out.printf("FileNotFoundException====>" + e);
        } catch (IOException e) {
            System.out.printf("IOException====>" + e);
        } catch (ClassNotFoundException e) {
            System.out.printf("ClassNotFoundException====>" + e);
        }
        return null;
    }
}

先序列化,才进行反序列化

Deserialization.person===>Person{age=10, name=‘测试‘, sex=‘女‘} 

给person增加字段,再用原来的序列化后的结果,进行反序列化;

package com.java.baseinfo.knowledge.code.serializable;

import java.io.Serializable;
public class Person implements Serializable { private int age; private String name; private String sex; // 增加字段测试序列化 private String addText; 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 String getAddText() { return addText; } public void setAddText(String addText) { this.addText = addText; } @Override public String toString() { final StringBuffer sb = new StringBuffer("Person{"); sb.append("age=").append(age); sb.append(", name=‘").append(name).append(‘\‘‘); sb.append(", sex=‘").append(sex).append(‘\‘‘); sb.append(", addText=‘").append(addText).append(‘\‘‘); sb.append(‘}‘); return sb.toString(); } }

 运行结果

IOException====>java.io.InvalidClassException: com.java.baseinfo.knowledge.code.serializable.Person; local class incompatible: stream classdesc serialVersionUID = 6964452789008335213, local class serialVersionUID = -3534890433624150186
Process finished with exit code 0  

 原因是:之前代码中未显示的指定UID,当Object中新增字段时,编译器又新生成一个UID,于是出现序列化版本不一致的问题;

2.2 显式指定UID

package com.java.baseinfo.knowledge.code.serializable;

import java.io.Serializable;

public class Person implements Serializable {

    private static final long serialVersionUID = -3534890433624150186L;
    private int age;

    private String name;

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

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("Person{");
        sb.append("age=").append(age);
        sb.append(", name=‘").append(name).append(‘\‘‘);
        sb.append(", sex=‘").append(sex).append(‘\‘‘);
        sb.append(‘}‘);
        return sb.toString();
    }
}

运行上述main函数, 先进行序列化,然后再对object增加属性,再序列化的结果,进行反序列化

package com.java.baseinfo.knowledge.code.serializable;

import java.io.Serializable;

public class Person implements Serializable {

    private static final long serialVersionUID = -3534890433624150186L;
    private int age;

    private String name;

    private String sex;

    // 增加字段测试序列化
    private String addText;

    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 String getAddText() {
        return addText;
    }

    public void setAddText(String addText) {
        this.addText = addText;
    }

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("Person{");
        sb.append("age=").append(age);
        sb.append(", name=‘").append(name).append(‘\‘‘);
        sb.append(", sex=‘").append(sex).append(‘\‘‘);
        sb.append(", addText=‘").append(addText).append(‘\‘‘);
        sb.append(‘}‘);
        return sb.toString();
    }
}

反序列化结果,新增的字段为空值

Deserialization.person===>Person{age=10, name=‘测试‘, sex=‘女‘, addText=‘null‘}
Process finished with exit code 0 

显式的指定UID,目前常用到的场景是:当object增加的字段时候,不希望反序列化出现异常,即希望类的不同版本对序列化兼容;

等用到其他场景的时候,再更新。。

参考:https://www.cnblogs.com/xdp-gacl/p/3777987.html

java_序列化

标签:增加   override   文本   catch   targe   int   app   ati   rgs   

原文地址:https://www.cnblogs.com/qrrlinux/p/10231975.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!