对象序列化和反序列化,以及类升级后兼容原来的数据

如题:当前的Person属性有[id,name,sex] ,通过序列化之后将对象数据存储在文档中

import java.io.Serializable;

/**
 * @ClassName Person
 * @Description 人类【对象流的使用】序列化需要实现
 * @Author chenxys
 * @Date 2022/2/21 11:05
 * @Version
 */
public class Person implements Serializable {
    //序列化的版本ID是在类进行升级改造之后,可以通过ID去反序列化数据回来,解决兼容性问题
    //例如: Person[id,name,sex] 把对象数据存储在文档中
    //升级改造 Person[id,name,sex,address]
    //由于版本ID的存在,即使类修改结构之后,都会认定为同一个版本,则可以进行反序列化
    private static final long serialVersionUID = 1L;//序列化ID
    private int id;
    private String name;
    private String sex;


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

    public Person() {
    }


    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    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("id=").append(id);
        sb.append(",name='").append(name);
        sb.append(",sex='").append(sex);
        sb.append("}");
        return sb.toString();
    }
}
import java.io.*;
/**
 * @ClassName ObjectStreamTest
 * @Description 对象序列化和反序列化
 * @Author chenxys
 * @Date 2022/2/21 11:07
 * @Version
 */
public class ObjectStreamTest {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //对象输出流--序列化操作
        ObjectOutputStream obs = new ObjectOutputStream(new FileOutputStream("/Users/chenys/Desktop/test1/text.txt"));
        //创建一个对象
        Person p = new Person(1,"赵","女");
        //写出
        obs.writeObject(p);
        //关闭流
        obs.close();

        //对象写入流--反序列化操作
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/Users/chenys/Desktop/test1/text.txt"));
        //读取
        Object obj = ois.readObject();
        //输出
        System.out.println(obj);
        //关闭流
        ois.close();
    }
}

当前结果:

Person{id=1,name='赵,sex='女}

对类进行升级:添加address属性并重写toString方法

package java_20220221.objectIO;

import java.io.Serializable;

/**
 * @ClassName Person
 * @Description 人类【对象流的使用】序列化需要实现
 * @Author chenxys
 * @Date 2022/2/21 11:05
 * @Version
 */
public class Person implements Serializable {
    //序列化的版本ID是在类进行升级改造之后,可以通过ID去反序列化数据回来,解决兼容性问题
    //例如: Person[id,name,sex] 把对象数据存储在文档中
    //升级改造 Person[id,name,sex,address]
    //由于版本ID的存在,即使类修改结构之后,都会认定为同一个版本,则可以进行反序列化
    private static final long serialVersionUID = 1L;//序列化ID
    private int id;
    private String name;
    private String sex;


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

    public Person() {
    }


    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    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("id=").append(id);
//        sb.append(",name='").append(name);
//        sb.append(",sex='").append(sex);
//        sb.append("}");
//        return sb.toString();
//    }

    类升级
    private String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

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

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("Person{");
        sb.append("id=").append(id);
        sb.append(",name='").append(name);
        sb.append(",sex='").append(sex);
        sb.append(",address='").append(address);
        sb.append("}");
        return sb.toString();
    }
}

因为版本ID的存在,即使类修改结构之后,都会认定为同一个版本,则可以进行反序列化

import java.io.*;
/**
 * @ClassName ObjectStreamTest
 * @Description 对象序列化和反序列化
 * @Author chenxys
 * @Date 2022/2/21 11:07
 * @Version
 */
public class ObjectStreamTest {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //对象写入流--反序列化操作
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/Users/chenys/Desktop/test1/text.txt"));
        //读取
        Object obj = ois.readObject();
        //输出
        System.out.println(obj);
        //关闭流
        ois.close();
    }
}

结果为:

Person{id=1,name='赵,sex='女,address='null}

综上:

序列化的版本ID是在类进行升级改造之后,可以通过ID去反序列化数据回来,解决兼容性问题
例如: Person[id,name,sex] 把对象数据存储在文档中
升级改造 Person[id,name,sex,address]
由于版本ID的存在,即使类修改结构之后,都会认定为同一个版本,则可以进行反序列化

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt的序列化(Serialization)功能允许你在程序之间或持久化存储中保存和恢复对象的状态。这是一项强大的工具,特别是在跨版本迁移或不同模块间传递数据时,能够保证数据的一致性和可读性。 **版本兼容性**在Qt序列化中是非常关键的。当你升级或改变应用程序的代码后,旧版本的程序可能无法读取新版本生成的数据,反之亦然。Qt提供了几种机制来处理版本兼容性: 1. **Qt Meta Object System (QMetaObject)**:使用QMetaObject可以创建具有不同版本的序列化数据。你可以设置元对象系统中的`Q_OBJECT`宏来启用序列化,并定义`Q_PROPERTY`来指定哪些属性需要被序列化。通过指定`Q_INVOKABLE`标志,函数也可以被序列化。Qt会自动处理不同版本之间的属性更改。 2. **qRegisterMetaType()**: 这个函数用于注册特定型的数据,以便于序列化。如果你在新版本中添加了新的数据型,需要确保在旧版本中也注册,或者为旧版本提供一种方法来忽略新数据。 3. **QDataStream**和`QTextStream`:在更新过程中,如果数据结构发生变化,你可以定义一个策略来处理旧版本的数据,比如跳过未知字段,或者为新字段提供默认值。 4. **Qt Serializers**: Qt提供了一些预编译的序列化库,如QSettings、QByteArray等,它们有自己的方式处理版本差异,例如提供不同的文件格式或版本号标记。 **相关问题--:** 1. 如何确保Qt对象在不同版本间的序列化一致性? 2. 在更新Qt应用程序时,如何处理已有的QDataStream或QTextStream数据格式变化? 3. Qt的哪些或工具可以帮助处理版本不兼容序列化问题?

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值