47序列化和反序列化
Posted zhuifeng-mayi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了47序列化和反序列化相关的知识,希望对你有一定的参考价值。
在工作中有可能遇到多台机器远程通信的情况,如果要将机器A中的某个java对象传输到机器B上面,需要将这个java对象转换为字节序列然后进行传输。将对象转换为字节序列的过程叫做序列化,反之叫做反序列化。
一个对象如果支持序列化,需要实现Serializable的接口,这个接口中没有任何方法,实现该接口后,JVM会给这个对象做特殊待遇
将java对象保存到硬盘里面
使用序列化还可以将一个对象保存到硬盘中,然后再通过反序列化将该对象读取到内存里面。
创建一个Student类,实现Serializable接口
package com.monkey1024.serializable; import java.io.Serializable; public class Student implements Serializable { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
使用ObjectOutputStream将Student对象写出到硬盘中
package com.monkey1024.serializable; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; /** * 将Student对象序列化到硬盘中 * */ public class ObjectOutput { public static void main(String[] args) { Student s = new Student(); s.setName("张三"); // 创建输出流(序列化流) try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("zhangsan"));) { //将对象写出到硬盘中 oos.writeObject(s); oos.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
使用ObjectInputStream将硬盘中的对象读取到内存中
package com.monkey1024.serializable; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.ObjectInputStream; /** * 从硬盘中读取Student对象 * */ public class ObjectInput { public static void main(String[] args) { try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("zhangsan"));) { Student s = (Student)ois.readObject(); System.out.println(s.getName()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
序列化版本号
在一个类实现Serializable接口后,系统会给每个对象一个序列化版本号,当这个类的源码被修改后,系统会重新分配一个新的序列化版本号,这样做的好处就是保证序列化和反序列化的对象内容一致。例如将一个对象序列化到硬盘之后,修改这个对象所对应类的源码,在进行反序列化是就会报出InvalidClassException异常。如果手动编写序列化版本号之后,就不会出现这个异常了。
package com.monkey1024.serializable; import java.io.Serializable; public class Student implements Serializable { /** * 自动生成序列化版本号 */ private static final long serialVersionUID = -716323668524282676L; private String name; private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
transient关键字
如果不希望将Student类中的age属性序列化,可以使用transient声明该属性,在序列化时将忽略这个属性。
package com.monkey1024.serializable; import java.io.Serializable; public class Student implements Serializable { /** * 自动生成序列化版本号 */ private static final long serialVersionUID = -716323668524282676L; private String name; //age不序列化 transient private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
以上是关于47序列化和反序列化的主要内容,如果未能解决你的问题,请参考以下文章