对象的序列化和反序列化---使用Serializable接口
来源:互联网 发布:mysql having 用法 编辑:程序博客网 时间:2024/06/05 03:26
什么是对象的序列化和反序列化?
对象序列化,就是将Object对象转换成byte字节序列;这里使用ObjectOutputStream — writeObject();
对象的反序列化,就是将byte字节序列转换成Object对象;这里使用ObjectInputStream—readObject();
Serializable接口
是java所提供的一个序列化方式,为对象提供标准的序列化和反序列化操作;
对象序列化需要实现Serializable接口,只是一个规定,标准,这个接口里面没有任何方法;
想让一对象实现序列化只要这个类实现Serializable接口并声明一个serialVersionUID,比如下面
public class Student implements Serializable { private static final long serialVersionUID = 8809363383079722734L; private int age; private String name; private String address; public Student() { super(); } public Student(int age, String name, String address) { super(); this.age = age; this.name = name; this.address = address; } @Override public String toString() { return "Student [age=" + age + ", name=" + name + ", address=" + address + "]"; }}
实际上这个serialVersionUID也不是必须的。我们不声明这个serialVersionUID同样也可以实现序列化。但这将会对反序列化过程产生影响。
这个serialVersionUID是用来辅助序列化和反序列化的,原则上序列化后的数据中的serialVersionUID只有和当前类的serialVersionUID相同才能够正常的被反序列化。
serialVersionUID的详细工作机制是这样的:
1.序列化的时候系统会把当前类的serialVersionUID写入序列化的文件中(也可能是其他的中介),
2.当反序列化的时候系统会去检测文件中的serialVersionUID,看它是否和当前类的serialVersionUID一致,
3.如果一致就说明序列化的类的版本和当前类的版本是相同的,这个时候可以反序列化;
如果不一致说明当前类和序列化的类相比发生了某些变化,比如成员变量数量、类型可能发生了变化,这时候无法正常反序列化。看下面示例演示序列化和反序列化
public class Main { public static void main(String[] args) { try { // 序列化 serialObject(); // 反序列化 reSerialObject(); } catch (Exception e) { e.printStackTrace(); } } // 序列化过程 private static void serialObject() throws IOException, FileNotFoundException { Student stu = new Student(10, "liming", "杨集"); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream( "student.txt")); oos.writeObject(stu); oos.close(); } // 反序列化过程 private static void reSerialObject() throws IOException, FileNotFoundException, ClassNotFoundException { ObjectInputStream ois = new ObjectInputStream(new FileInputStream( "student.txt")); Student student = (Student) ois.readObject(); ois.close(); System.out.println(student.toString()); }}
上面如果正常的话,是可以完整进行序列化和反序列化工作的,现在如果我们注释反序列化方法reSerialObject(),运行代码先执行序列化,然后在改动如下信息:
1,将Student类中的private static final long serialVersionUID = 1L;
2,注释掉序列化的代码,去掉反序列化的注释。在运行一下:
这时反序列化就会出问题了,报如下错误:
Exception in thread "main" java.io.InvalidClassException: com.io.test.Student; local class incompatible: stream classdesc serialVersionUID = 8809363383079722734, local class serialVersionUID = 1 at java.io.ObjectStreamClass.initNonProxy(Unknown Source) at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source) at java.io.ObjectInputStream.readClassDesc(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.readObject(Unknown Source) at com.io.test.Main.main(Main.java:28)
这个手序列化就会失败了!
transient关键字可以使得某个字段不被序列化;
private transient String address;//系统默认不会被jVM序列化
其实系统默认序列化的方式可以可以通过重写readObject()和writeObject方法来改变,比如下面的例子
public class Student implements Serializable { private static final long serialVersionUID = 8809363383079722734L; private int age; private String name; private transient String address;//默认是不能序列化的,但是重写了上面两个方法,所以也可以序列化和反序列化 public Student() { super(); } public Student(int age, String name, String address) { super(); this.age = age; this.name = name; this.address = address; } @Override public String toString() { return "Student [age=" + age + ", name=" + name + ", address=" + address + "]"; } /**重写系统反序列化的方法*/ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject();// JVM虚拟机默认的反序列化过程 address = s.readUTF();//反序列化address } /**重写系统序列化的方法*/ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { s.defaultWriteObject();// JVM虚拟机默认的序列化过程 s.writeUTF(address);//序列化address }}
到此介绍完毕~~~
- 对象的序列化和反序列化---使用Serializable接口
- Java对象的序列化和反序列化Serializable
- java IO ObjectInputStream 对象序列化和反序列化 还有序列化接口Serializable的作用
- Serializable 接口(序列化和反序列化)
- Serializable,序列化和反序列化
- Serializable序列化和反序列化
- Serializable 序列化和反序列化
- Serializable序列化和反序列化 .
- 序列化和反序列化Serializable
- java序列化(Serializable)的作用和反序列化
- java序列化(Serializable)的作用和反序列化
- java序列化(Serializable)的作用和反序列化
- java序列化(Serializable)的作用和反序列化
- java序列化(Serializable)的作用和反序列化
- java序列化(Serializable)的作用和反序列化
- java序列化(Serializable)的作用和反序列化
- java序列化(Serializable)的作用和反序列化
- java序列化(Serializable)的作用和反序列化
- 线程安全随机队列
- 安装eclipse的JRebel6.4.3的插件
- hibernate在不联网时不能解析配置文件解决方案
- leetcode318:Maximum Product of Word Lengths(medium)
- iOS --- 一张图看懂转场动画
- 对象的序列化和反序列化---使用Serializable接口
- scala进阶14-自身类型self type
- 蚁群算法
- log4j.properties配置详解
- resolve in ui-router
- HDU 1052 Tian Ji -- The Horse Racing
- 遗传算法
- Java常量和变量及数据类型
- python学习笔记二(pandas基础)