对象的序列化和反序列化
来源:互联网 发布:日本机器人 知乎 编辑:程序博客网 时间:2024/06/06 01:23
22,ObjectInputStream和ObjectOutputStream
22.1对象的序列化流和反序列化流
这两个流对象是用来操作对象的。
对象的序列化:就是让对象中封装的数据可以持久化存储。
对象的反序列化:就是通过存储的文件数据获取对象实体。
对象序列化的条件:
必须要实现Serializable接口,否则无法实现对象的序列化。此接口提供了一个serialVersionUID,用于验证序列化和反序列化时是否是同一个对象,如果不是则无法反列化。
ObjectInputStream和ObjectOutputStream都是装饰类,用于增强流对象的功能。
其构造函数:
ObjectInputStream
(InputStream out)
ObjectOutputStream
(OutputStream out)
分别都接收一个字节流。
22.2对象的序列化
用到的流对象是:ObjectOutputStream
使用其方法:writerObject(被序列化的对象);
多个对象,就多次调用writerObject().
注意:对象的序列化,只存储对象中非瞬态和非静态的字段。
如:
import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectOutputStream;import java.io.Serializable;public class ObjectOutputStream Demo { public static void main(String[] args)throws FileNotFoundException, IOException { //创建对象序列化流,将对象的数据保存在,指定的文件中。 ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("d:\\person.object")); //序列化对象。 oos.writeObject(new Person("李四",44)); //关闭资源 oos.close(); }}class Person implements Serializable{//对象要序列化必须要实现此接口 private String name; private int age; public Person(String name,int age) { super(); 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; } }
22.3对象的反序列化
对象的反序列化使用流对象:ObjectInputStream
使用方法:readObject();此方法返回Object对象,需要进行强转。
多个对象被反序列化,就多次调用readObject()每次读取一个对象。
通过读取被序列化对象的文件,获取对象。
如:
import java.io.FileInputStream;import java.io.FileNotFoundException;importjava.io.FileOutputStream;import java.io.IOException;import java.io.ObjectInputStream;importjava.io.ObjectOutputStream;import java.io.Serializable;public class ObjectOutputStream Demo { public static void main(String[] args)throws ClassNotFoundException, FileNotFoundException, IOException { //创建对象序列化流,将对象的数据保存在,指定的文件中。 ObjectInputStream ois=new ObjectInputStream(new FileInputStream("d:\\person.object")); //反序列化对象。 Person p=(Person)ois.readObject(); System.out.println(p.getName()+"::"+p.getAge()); //关闭资源 ois.close(); }}/* *打印结果:李四::44 */
通过反序列化流,可以从一个存储对象数据的文件中获取这个对象,实现了对象数据的持久化存储和对象的获取。
注意:对象反序列化时要获取对象,必须要满足:
1, 有对象的序列化文件。
2, 要有对象所属的字节码文件。否则,无法获取对象。
如果一个对象被序列化后,其原有的数据被修改,这时就不能完成反序列化。
异常信息:
Exception in thread "main"java.io.InvalidClassException: IO流.Person; local class incompatible: stream classdesc serialVersionUID = -5252691168862610579, local class serialVersionUID = -7585441751578431892
这是因为serialVersionUID号不一致造成的,对象的反序列化过程中,会检查这个版本号与原对象的版本号是否一致,如果不一致就无法完成反序化,serialVersionUID在类中如果没有明确声明的情况下,会根据类中的内容默认计算出一个,当然,也可在类中自己声明一个serialVersionUID,不管类中数据是否变化,只要此号不变,就可以完成反序列化。
如:
class Person implements Serializable{//对象要序列化必须要实现此接口 private static final long serialVersionUID = 1L;//显示声明serialVersionUID private int age; private String name; public Person(String name,int age) { super(); 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; }}
22.4关键字transient(瞬态)
对象的序列化,其静态和非瞬态的字段是不能被存储到文件中的。
如果一个字段不是静态,但也不想被存储到文件中,就可以加上此关键字:transient
如:
import java.io.FileInputStream;import java.io.FileNotFoundException;importjava.io.FileOutputStream;import java.io.IOException;import java.io.ObjectInputStream;importjava.io.ObjectOutputStream;import java.io.Serializable;public class ObjectOutputStreamDemo { public static void main(String[] args)throws ClassNotFoundException, FileNotFoundException, IOException { //创建对象序列化流,将对象的数据保存在,指定的文件中。 ObjectInputStream ois=new ObjectInputStream(new FileInputStream("d:\\person.object")); //反序列化对象 Person p=(Person)ois.readObject(); System.out.println(p.getName()+"::"+p.getAge()); //关闭资源 ois.close(); }}class Personimplements Serializable{//对象要序列化必须要实现此接口 private static final long serialVersionUID = 1L;//显示声明serialVersionUID private static int age;//静态属性 private transient String name;//瞬态属性 public Person(String name,int age) { super(); 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; }}/* *反序列化打印结果:null::0 */
注意:多个对象的序列化,就多次调用writeObject(),多个对象的反序列化就多次调用readObject(),有几个对象就读取几个。
import java.io.FileInputStream;import java.io.FileNotFoundException;importjava.io.FileOutputStream;import java.io.IOException;import java.io.ObjectInputStream;importjava.io.ObjectOutputStream;import java.io.Serializable; public class ObjectOutputStream Demo { public static void main(String[] args)throws ClassNotFoundException, FileNotFoundException, IOException {// ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("d:\\person.object")); //序列化多个对象// oos.writeObject(new Person("李四",33));// oos.writeObject(new Person("张三",24));// oos.writeObject(new Person("小强",45));// oos.writeObject(new Person("李明",23));// oos.close(); //创建对象序列化流,将对象的数据保存在,指定的文件中。 ObjectInputStream ois=new ObjectInputStream(new FileInputStream("d:\\person.object")); //反序列化多个对象。 Person p1=(Person)ois.readObject(); Person p2=(Person)ois.readObject(); Person p3=(Person)ois.readObject(); Person p4=(Person)ois.readObject(); System.out.println(p1.getName()+"::"+p1.getAge()); System.out.println(p2.getName()+"::"+p2.getAge()); System.out.println(p3.getName()+"::"+p3.getAge()); System.out.println(p4.getName()+"::"+p4.getAge()); //关闭资源 ois.close(); }}class Person implements Serializable{//对象要序列化必须要实现此接口 private static final long serialVersionUID = 1L;//显示声明serialVersionUID private int age; private String name; public Person(String name,int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } publicvoid setName(String name) { this.name = name; } publicint getAge() { return age; } publicvoid setAge(int age) { this.age = age; }} /* *打印结果:李四::33张三::24小强::45李明::23 */
总结:对象的序列化和反序列化可以将对象持久保存,并可以随时获取对象,实现了对象中数据的持久保存。对象要序列化必须要实现Serializable接口,并声明serialVersionUID号,以免反序列化时抛出异常。对象反序列化要获取对象,首先必须有保存对象的文件,其实,必须有对象所属的字节码文件。对象中的静态字段和transient修饰的字段是不能被序列化到文件中的。
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
- 对象序列化和反序列化
- 对象序列化和反序列化
- 对象序列化和反序列化
- 对象序列化和反序列化
- 对象序列化和反序列化
- 对象序列化和反序列化
- 对象序列化和反序列化
- 对象序列化和反序列化
- 对象序列化和反序列化
- .NET对象的XML序列化和反序列化
- .NET对象的XML序列化和反序列化
- 对象的序列化和反序列化
- 对象的序列化和反序列化
- 对象的序列化和反序列化
- 对象的序列化和反序列化实践
- 关于复杂对象的序列化和反序列化
- 对象的序列化和反序列化实践
- 剖析对象的序列化和反序列化
- Java内存泄露
- 6-使用VMWARE虚拟机调试XPE的方法
- css学习笔记---盒模型,布局
- 代理模式
- 网站前端性能优化
- 对象的序列化和反序列化
- 常见C/C++ XML解析器比较
- strcpy,strncpy和strncpy_s的区别 strncpy函数与memcpy函数
- Android虚拟机提示The connection to adb is down, and a severe error has occured
- cocos2d-x3.0输入框
- 3DMAX经典问答---材质部分(3)
- ubuntu server 安装桌面环境中文乱码问题
- Thinkpad x230i预装Windows 8的机型更换Windows 7及XP的常规设置方法
- MYSQL limit,offset 区别