}
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