Java之序列化和反序列化,牛皮轰轰

}

public void setName(String name) {

this.name = name;

}

}

序列化操作

实现序列化必须实现Serializable接口,如果没有实现这个接口就会报错——NotSerializableException;

序列化代码实现

//序列化

private static void serialization() {

//创建一个Person对象

Person person = new Person();

person.setId(100);

person.setName(“Java”);

String filePath = “D:\io_test\2\person.txt”;

try {

ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(filePath));

//序列化要调用writeObject()方法,然后将对象传进去

objectOutputStream.writeObject(person);

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

执行结果,打开person文档查看结果其内容被序列化成二进制

在这里插入图片描述

反序列化操作

//反序列化,因为反序列化会把二进制转换成一个对象,所以返回值就使用定义的Person

private static Person deserialization() {

//创建一个对象用来接收

Person person = null;

//反序列化需要操作的文件地址,也就是我们刚刚序列化的文件

String filePath = “D:\io_test\2\person.txt”;

try{

ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filePath));

{

//这里需要将强转成Person类

person = (Person) objectInputStream.readObject();

}

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

return person;

}

如何验证反序列成功了呢?那就将他的属性打印出来,如果是我们最初定义的值,那么就是成功的

在这里插入图片描述

序列化和反序列化注意问题


注意问题一:版本号UID,也就是当一个文件被序列化之后,然后再类里面添加其他属性的时候,此时反序列化的结果是读取不到新添加的属性的值

在这里插入图片描述

那么如何解决这个自定义类不一致的问题呢?就需要使用UID,可以看到,如果不定义一个UID那么Java内部会自定义的设置两个不同的UID

在这里插入图片描述

在Person里面定义一个serialVersionUID

在这里插入图片描述

测试代码:

测试步骤:

1.进行序列化操作

2.添加新的属性name

3.进行反序列化查看结果(结果是对应的属性,如String就会返回null)

序列化部分

import java.io.*;

/**

  • 版本UID问题

*/

public class IoDemo12 {

static class Person implements Serializable {

public final static long serialVersionUID = 1L;

private int id;

private int age;

private String name;

public String getName()

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

{

return name;

}

public void setName(String name) {

this.name = name;

}

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

}

public static void main(String[] args) {

Person person = new Person();

person.setId(111);

person.setAge(18);

person.setName(“豹子头”);

//需要将二进制存在哪里的路径

String filePath = “D:\io_test\2\person1”;

try {

ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(filePath));

{

//进行序列化操作

objectOutputStream.writeObject(person);

}

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

}

反序列化部分

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.ObjectInputStream;

public class IoDemo13 {

public static void main(String[] args) {

IoDemo12.Person person = null;

String filePath = “D:\io_test\2\person1”;

try{

ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filePath));

{

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

}

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

System.out.println(“person id :”+person.getId());

System.out.println(“person name :”+person.getName());

}

}

执行结果

在这里插入图片描述

总结:

serialVersionUID可以控制版本了,当出现版本不一致的情况,就能够迅速定位到问题并解决,如果不设置UID(不修改)就会造成,读取数据为(引用类型)null/(int)0的业务逻辑问题(假如时新的版本就可以正常读取到值,可以进行下面的业务逻辑,反之,如果时旧版本的二进制序列化文件,可以进行舍弃)

1.当进行序列化和反序列化时显示的设置此值

2.每次对实体类进行修改之后更新UID的值

注意问题二:临时变量——transient

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值