魏县网站建设,东莞网站建设模板设计,网站建设在国内外研究现状,个人网站搭建详细步骤文章目录1.概述2.特点/应用场景3.涉及到的流对象4.代码实现序列化与反序列化4.1 步骤1#xff1a;创建学生类Student24.2 步骤2#xff1a;创建序列化测试类5.测试案例中常见的几种编译错误类型6.为什么反序列化版本号需要与序列化版本号一致#xff1f;7.自动提示 生成UID … 文章目录1.概述2.特点/应用场景3.涉及到的流对象4.代码实现序列化与反序列化4.1 步骤1创建学生类Student24.2 步骤2创建序列化测试类5.测试案例中常见的几种编译错误类型6.为什么反序列化版本号需要与序列化版本号一致7.自动提示 生成UID 链接的设置1.概述 序列化 ObjectOutputStream 是指把程序中的java对象通过序列化流oos输出到磁盘的文件中相当于数据写出的过程利用ObjectOutputStream,把对象的信息,按照固定的格式转成一串字节值输出并持久保存到磁盘方向是OUT使用的流是ObjectOutputStream使用的方法是out.writeObject(目标对象)注意如果一个类的对象想要被序列化那么这个类必须实现Serializable接口 反序列化 ObjectInputStream 是指把之前已经保存在文件中的对象的相关数据通过反序列化流ois读到内存中的过程中并把读到的数据恢复成对象利用ObjectInputStream,读取磁盘中之前序列化好的数据,重新恢复成对象相当于数据读取的过程方向是in使用的流是ObjectInputStream使用的方法是in.readObject();注意反序列化指定的文件路径必须与序列化输出的文件路径一致注意一次序列化操作对应一次反序列化操作或者UID必须保持一致如果不一致会报错 2.特点/应用场景
需要序列化的文件必须实现Serializable接口,用来启用序列化功能不需要序列化的数据可以修饰成static,原因:static资源属于类资源,不随着对象被序列化输出每一个被序列化的文件都有一个唯一的id,如果没有添加此id,编译器会自动根据类的定义信息计算产生一个在反序列化时,如果和序列化的版本号不一致,无法完成反序列化常用与服务器之间的数据传输,序列化成文件,反序列化读取数据常用使用套接字流在主机之间传递对象不需要序列化的数据也可以被修饰成transient(临时的),只在程序运行期间在内存中存在,不会被序列化持久保存
3.涉及到的流对象
序列化Object OutputStream ObjectOutputStream 将 Java 对象的基本数据类型写入 OutputStream通过在流中使用文件可以实现对象的持久存储。如果流是网络套接字流则可以在另一台主机上或另一个进程中重构对象。 构造方法: ObjectOutputStream(OutputStream out) 创建写入指定 OutputStream 的 ObjectOutputStream 普通方法: writeObject(Object obj) 将指定的对象写入 ObjectOutputStream 反序列化ObjectInputStream ObjectInputStream对以前使用ObjectOutputStream写入的基本数据和对象进行反序列化重构对象。 构造方法: ObjectInputStream(InputStream in) 创建从指定 InputStream 读取的 ObjectInputStream 普通方法: readObject() 从 ObjectInputStream 读取对象 4.代码实现序列化与反序列化
4.1 步骤1创建学生类Student2
package partThree;
/*本类用于序列化测试的物科类*/
public class Student2 {//定义学生相关的属性并进行封装private String name; //姓名private int age; //年龄private String addr; //地址private char gender;//性别//2.1 创建本类的无参构造--注意必须手动提供无参构造否则会被覆盖public Student2() {System.out.println(我是Student的无参构造);}//2.2创建全参构造public Student2(String name, int age, String addr, char gender) {super();//默认调用父类的无参构造this.name name;this.age age;this.addr addr;this.gender gender;System.out.println(我是Student的全参构造);}//3.属性封装后,需要本类提供公共的属性访问与设置方式get()set()/*** 自动创建get()set(),右键--Source--Generate Getters and Setters...*/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;}public String getAddr() {return addr;}public void setAddr(String addr) {this.addr addr;}public char getGender() {return gender;}public void setGender(char gender) {this.gender gender;}//如果不想查看对象的地址值而是想查看类型 属性 属性值//可以在子类中添加重写的toString()Overridepublic String toString() {return Student{ name name \ , age age , addr addr \ , gender gender };}
}4.2 步骤2创建序列化测试类
package partThree;import java.io.*;/* 本类用于测试对象的序列化与反序列化* 序列化 ObjectOutputStream* 是指把程序中的java对象通过序列化流oos输出到磁盘的文件中相当于数据写出的过程* 反序列化 ObjectInputStream* 是指把之前已经保存在文件中的对象的相关数据通过反序列化流ois读到内存中的过程中* 相当于数据读取的过程*/
public class TestSerializable {public static void main(String[] args) {method1(); //本方法用来完成序列化的功能method2(); //本方法用于完成反序列化功能}private static void method2() {//1.定义一个在本方法中都生效的局部变量注意初始化ObjectInputStream in null;//2.由于IO操作可能会产生异常所以完成try-catch-finally结构try{//3.创建反序列化流oisin new ObjectInputStream(new FileInputStream(E:\\ready\\1.txt));//4.通过反序列化流读取文件中的数据并把读到的数据回复成数据Object o in.readObject();System.out.println(o); //将接到的对象打印System.out.println(恭喜您反序列化成功);}catch(Exception e){System.out.println(很抱歉反序列化失败);e.printStackTrace();}finally {try {in.close();} catch (IOException e) {e.printStackTrace();}}}private static void method1() {//定义一个在本方法中都生效的局部变量注意初始化ObjectOutputStream out null;try {//1.创建流对象--需要try-catch需要设置FileOutputStream子类// 并设置传输文件路径表明要把序列化后的对象数据输出到哪个文件中out new ObjectOutputStream(new FileOutputStream(E:\\ready\\1.txt));//2.使用流对象//2.1 指定一个要序列化输出的对象并设置属性Student2 s new Student2(海绵宝宝,3,海里,男);//2.2 序列化输出对象s到文件中out.writeObject(s);System.out.println(恭喜您序列化成功);//成功后我们可以在目标文件里看到序列化输出的数据但注意这个数据是为了底层保存对象和传输使用的我们看不懂//有些类似于我们字节码文件中的数据} catch (IOException e) {System.out.println(很抱歉序列化失败);e.printStackTrace();}finally {//3.关闭流对象try {out.close();} catch (IOException e) {e.printStackTrace();}}}
}5.测试案例中常见的几种编译错误类型 NotSerializableException:报错原因:要序列化对象所在的类并没有实现序列化接口 解决方案:实现序列化接口 InvalidClassException:报错原因:更改子类数据后会导致本次反序列化时使用的UID与序列化时的UID不匹配 解决方案:反序列化时的UID与序列化时的UID要保持一致或者测试时一次序列操作对应一次反序列化操作,否则不匹配就报错重新进行一次序列化后再进行反序列化即可
6.为什么反序列化版本号需要与序列化版本号一致
我们在反序列化时JVM会拿着反序列化流中的serialVersionUID与序列化时相应的实体类中的serialVersionUID来比较如果不一致就无法正常反序列化出现序列化版本不一致的异常InvalidClassException。
而且我们在定义需要序列化的实体类时如果没有手动添加UID, Java序列化机制会根据编译的class自动生成一个那么只有同一次编译生成的class才是一样的UID。
如果我们手动添加了UID,只要这个值不修改就可以不论编译次数进行序列化和反序列化操作。
7.自动提示 生成UID 链接的设置