写点什么

Java 笔记 IO —— 序列化和反序列化,面试大厂应该注意哪些问题

作者:Java高工P7
  • 2021 年 11 月 10 日
  • 本文字数:1439 字

    阅读完需:约 5 分钟

}


public static void write() throws IOException {


//ObjectOutputStream(OutputStream out)


// 创建一个写入指定的 OutputStream 的 ObjectOutputStream


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


//创建一个 Person 类对象


Person p = new Person("zhang",15);


//void writeObject(Object obj)


//将指定的对象写入 ObjectOutputStream


oos.writeObject(p);


//关闭流


oos.close();


}


}


控制台结果



obj.txt 文件里面的内容



这个内容看不懂属于正常情况,这是序列化后的内容结果


package review.IO;


import java.io.Serializable;


public class Person implements Serializable {


public String name;


public int age;


public Person() {


}


publi


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


c Person(String name, int age) {


this.name = name;


this.age = age;


}


public String getName() {


return name;


}


public void setName(String name) {


this.name = name;


}


public int getAge() {


return age;


}


public void setAge(int age) {


this.age = age;


}


@Override


public String toString() {


return "Person{" +


"name='" + name + ''' +


", age=" + age +


'}';


}


}


这是被序列化的对象的类的具体内容


关于这个类需要注意的事情:


(一)被序列化的对象的类必须实现了 Serializable 接口,否则会报 java.io.NotSerializableException 未序列化异常


jdk1.8 文档中的描述是:


类的序列化由实现 java.io.Serializable 接口的类启用,不实现此接口的类将不会使任何状态序列化或反序列化。


可序列化类的所有子类型都是可序列化的。序列化接口没有方法或字段,仅用于标识可串行化的语义。


(二)Stream 流中的 class 类与本地文件中的 class 类,应该是相同的


这里的 class 类是 Person 类,


我用上面的 Person 类代码运行 write()方法,进行序列化,写入到文件中。


然后我对这个 Person 类进行修改,比如将 public int age 改成 private int age。


最后运行 read()方法,读取内容,就会报错


报错内容是


java.io.InvalidClassException: review.IO.Person; local class incompatible:


stream classdesc serialVersionUID = -4369,


local class serialVersionUID = 8665(这里的 UID 数字太长,为了方便看我只截取四位)


造成这个异常的原因是,Person 类实现了 Serializable 标记接口,它本身就会有一个标记值。


在修改 Person 类之前,假设 Person.class 的标记值 id 是 1000


在没有修改 Person 类的之前:


Person.class —— id=1000


写数据的时候 :obj.txt —— id=1000


读数据的时候 :obj.txt —— id=1000


往文件里面写入类对象,和从文件里面还原类对象的时候,文件中的 class 类的标记值一直是 1000,因为写入的时候标记值 id 是 1000。在读文件的时候,会将这个 id=1000 与本地文件的 Person 类的 id 做对比,如果相同才能还原成 Person 类对象


进行修改后:(把 public 换成 private,也就是对 Person 类进行修改)


Person.class —— id=2000


写数据的时候 :obj.txt —— id=1000


读数据的时候 :obj.txt —— id=1000


此时因为是修改前把对象写入文件中,所有这里的 id 值不会改变。但是读取的时候,会将 obj.txt 文件里的 id 与本地文件的 Person 类的 id 做对比,这里因为修改过了 Person 类,导致两个 id 是不一样的,所以会报错。


但是,修改了一个类中的某一处地方,这个类的大体构造还是没有变的,我们不希望因为一点变动就改变类的 id。因此可以用 serialVersionUID 来固定一个 class 文件的 id 值


先选中这里的选项并应用



用户头像

Java高工P7

关注

还未添加个人签名 2021.11.08 加入

还未添加个人简介

评论

发布
暂无评论
Java笔记 IO —— 序列化和反序列化,面试大厂应该注意哪些问题