java 序列化 引用_java对象引用的序列化

如果某个类的成员变量的类型不是基本类型或String类型,而是另一个引用类型,那么这个引用类必须是可序列化的,否则拥有该类型成员变量的类也是不可序列化的

如果多次请同一个对象序列化,java只会储存一个对象,后续的都只是存储一个编号,具体的序列化算法如下:

所有保存到磁盘中的对象都有一个序列化编号

当程序试图序列化一个对象时,程序将先检查该对象是否已经被序列化过,只有该对象从未(在本次虚拟机中)被序列化过,系统才会将该对象转换成字节序列并输出

如果某个对象已经序列化过,程序将只是直接输出一个序列化编号,而不是再次重新序列化该对象

Person 类

@Data

public class Person implements Serializable {

private String name;

private int age;

public Person(String name, int age) {

this.name = name;

this.age = age;

}

}

Teacher 类拥有 Person 类实例

@Data

public class Teacher implements Serializable {

private String name;

private Person student;

public Teacher(String name, Person student) {

this.name = name;

this.student = student;

}

}

将 Teacher 类多次序列化

public class WriteTeacher {

public static void main(String[] args) {

try (

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("teacher.txt"));

) {

Person per = new Person("孙悟空", 2500);

Teacher t1 = new Teacher("唐僧", per);

Teacher t2 = new Teacher("菩提祖师", per);

// 将对象写入输出流

oos.writeObject(t1);

oos.writeObject(t2);

oos.writeObject(per);

oos.writeObject(t2);

} catch (IOException e) {

e.printStackTrace();

}

}

}

问题来了,序列化的四个对象中,Person 对象是不是同一个?

public class ReadTeacher {

public static void main(String[] args) {

try (

ObjectInputStream ois = new ObjectInputStream(new FileInputStream("teacher.txt"));

){

Teacher t1 = (Teacher) ois.readObject();

Teacher t2 = (Teacher) ois.readObject();

Person p = (Person) ois.readObject();

Teacher t3 = (Teacher) ois.readObject();

System.out.println("t1 的 student 引用和 p 是否相同 " + (t1.getStudent() == p));

System.out.println("t2 的 student 引用和 p 是否相同 " + (t2.getStudent() == p));

System.out.println("t2 和 t3 是否是同一个对象:" + (t2 == t3));

} catch (IOException | ClassNotFoundException e) {

e.printStackTrace();

}

}

}

b128277fb0665cbc5dba8736178363ce.png

如图,序列化一个对象多次,只会保存一次

因为 Java 的序列化机制,我们要注意以下场景:如果多次序列化同一个Java对象时,只有第一次序列化时才会把该Java对象转换成字节序列并输出,这样可能引起一个潜在的问题——当程序序列化一个可变对象时,只有第一次使用writeObject()方法输出时才会将该对象转换成字节序列并输出,当程序再次调用writeObject()方法时,程序只是输出前面的序列化编号,即使后面该对象的实例变量值已被改变,改变的实例变量值也不会被输出

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值