黑马程序员 对象序列化
来源:互联网 发布:电脑有些什么软件 编辑:程序博客网 时间:2024/05/23 05:07
-------------------android培训、 java培训、期待与您交流!-------------------
对象序列化
对象序列化的目的是将对象保存到磁盘中,或允许在网络中直接传输对象,对象序列化机制运行把内存中的Java对象转换成平台无关的二进制流,从而允许把这个二进制流持久保存在磁盘上,通过网络将这种二进制流传输到另一个网络节点。其他程序一旦获得了这个二进制流,都可以将这种二进制流恢复成原来的Java对象。
对象序列化将一个Java对象写入IO流中,对象的反序列化则是从IO流中恢复该Java对象。
Java对象实现序列化的方式:
(1)实现Serializaable接口,该接口是一个标记接口,实现该接口无须实现任何方法,它只是表明该类的实例是可以序列化的。
(2)实现Externalizable接口,
使用对象流实现序列化
通过对象流实现序列化的步骤:
(1)创建一个ObjectOutputStream输出流。
(2)调用OjbectOutputStream对象的writeObject方法输出可序列化对象。
实例:
public classSerializableTest { public static void main(String[] args) { ObjectOutputStream oos = null; try { oos = new ObjectOutputStream(newFileOutputStream("e:\\test.txt")); Person p = new Person("Android",7); // 将p对象写入输出流 oos.writeObject(p); } catch (IOException e) { e.printStackTrace(); } finally { if (oos != null) { try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } } } } class Personimplements 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; } }
反序列化的步骤:
(1)创建一个ObjectInputStream输入流。
(2)调用ObjectInputStream对象的readObject方法读取流中的对象。该方法返回一个Object类型的java对象。
实例:
public static void main(String[] args) { ObjectInputStream ois = null; try { //创建一个ObjectInputStream输出流 ois = new ObjectInputStream(newFileInputStream("e:\\test.txt")); //从流中读取一个java对象 Person p = (Person)ois.readObject(); System.out.println("name=" + p.getName() + " ,age=" + p.getAge()); } catch (IOException e) { // TODO Auto-generated catchblock e.printStackTrace(); } catch (ClassNotFoundException e){ // TODO Auto-generated catchblock e.printStackTrace(); } finally { if (ois != null) { try { ois.close(); } catch (IOException e) { // TODO Auto-generatedcatch block e.printStackTrace(); } } } }
反序列化机制无须通过构造器来初始化Java对象。如果反序列化某个子类实例时,反序列化机制需要恢复其关联的父类实例,恢复这些父类实例有两种方式:使用反序列化机制;使用父类无参数的构造函数。
如果一个可序列化类有多个父类(直接父类或间接父类),则该类的所有父类要么是可序列化的,要么有无参数的构造器,否则序列化时抛出IvaalidClassException异常。
对象引用的序列化
当程序序列化一个对象时,如果该对象持有一个其他对象的引用,为了在反序列化时可以正常恢复该对象,则程序会顺便把他引用的其他对象也进行序列化,否则该对象不能进行序列化。
Java序列化机制采用了一种特殊的序列化算法,其内容如下:
(1)所有保存到磁盘中的对象都有一个序列化编号。
(2)当程序试图序列化一个对象时,程序将先检测该对象是否已经序列化过,只有当该对象从未被序列化过,系统才会将该对象转换成字节序列并输出。
(3)如果某个对象是已经序列化过的,程序将直接只输出一个序列化编号,而不是再次重新序列化该对象。
注意:当使用Java序列化机制序列化可变对象时,一定要注意,只有当第一次调用wirteObject方法来输出对象时才会将对象转换为字节序列,并写出到ObjectOutputStream;在后面程序中,如果该对象的属性发送改变,即再次调用wirteObject方法输出该对象时,改变后的属性不会被输出。
自定义序列化
递归序列化:当对某个对象进行序列化时,系统会自动把该对象的所有属性依次进行序列化,如果某个属性引用到另一个对象,则被引用的对象也会被序列化。如果被引用的对象的属性也应用了其他对象,则被引用的对象也会被序列化。
通过在属性前加transient关键字,可以指定Java序列化时无须理会该属性,transient关键字只能用来修饰属性,不可以修饰Java程序中其他部分。比如: private transient int age;
但使用transient关键字修饰属性虽然很简单方便,但被transient修饰的属性将被完全隔离在序列化机制之外,这样导致在反序列化恢复Java对象时无法获得该属性值。Java提供了一种自定义序列化机制,通过这种自定义序列化机制可以让程序控制如何序列化各属性,甚至完全不序列化某些属性。
自定义序列化需要对如下个方法进行处理
(1)private void writeObject(java.io.ObjectOutputStream out) throws IOException;
(2)private void readObject(java.io.ObjectInputStream in) throwsIOException,ClassNotFoundException;
(3)private void readObjectNoData()throwsObjectStreamException;
writeObject方法负责写入特定类的实例的状态,以便相应的readObject方法可以恢复它。通过重写该方法,程序员可以完全获得对序列化机制的控制,程序员可以自主决定那些属性需要序列化,需要怎样序列化。默认情况下,该方法会调用out.defaultWriteObject来保存Java对象的各属性,从而可以实现序列化Java对象状态的目的。
readObject方法负责从流中读取并恢复对象属性,通过重写该方法,程序员可以完全获得对反序列化机制的控制,可以自主决定需要反序列化那些属性,以及进行怎样的反序列化。默认情况下,该方法会调用in.defaultReadObject来恢复Java对象的非静态属性,通常情况下readObject方法与readObject对应,如果writeObject方法中对Java对象的属性进行了一些处理,则应该在readObject方法中对该属性进行相应的反处理,以便正确恢复该对象。
当序列化流不完整时,readObjectNoData方法可以用来正确地初始化反序列化的对象。
Externalizable自定义序列化机制
Java还提供了另一种序列化机制,这种序列化方式完全由程序员决定存储和恢复对象数据,要实现该目的,java类必须实现Externalizable接口。
Externalizable接口定义的两个方法:
(1)void readExternal(ObjectInput in):需要序列化的类实现readExternal方法来实现反序列化。该方法调用DataInput(它是ObjectInput的父接口)的方法来恢复基本类似的属性值,调用ObjectInput的readObject方法来恢复引用类型的属性值。
(2)void writeExternal(ObjectOutput out):需要序列化的类实现writeExternal方法来保存对象的状态,该方法调用DataInput(它是ObjectInput的父接口)的方法来保存基本类型的属性值,,调用ObjectOutput的writeObject方法来保存引用类型的属性值。
-------------------android培训、 java培训、期待与您交流!-------------------
- 黑马程序员 对象序列化
- 黑马程序员---对象序列化
- 黑马程序员_对象的序列化
- 黑马程序员之Java--对象序列化
- 黑马程序员-学习对象序列化日记
- 黑马程序员----Java对象序列化
- 黑马程序员-----IO之对象流和对象序列化
- 黑马程序员_IO_file对象以及对象序列化
- 黑马程序员-序列化
- 黑马程序员-对象的序列化和管道流
- 黑马程序员_IO流——对象的序列化
- 黑马程序员--javaSE--对象序列化-字符串-Properties类
- 黑马程序员-学习日志-对象的序列化
- 黑马程序员-----IO之深入对象序列化
- 黑马程序员-----IO之对象序列化Externalizable与序列号
- 黑马程序员 C#学习笔记⑨ 序列化对象
- 黑马程序员——Java 对象序列化
- 黑马程序员----java基础--------对象的序列化
- 数据的导出与导入(数据库)
- CCNA----NAT网络地址转换
- yii CActiveDataProvider可配参数
- How-To Create Multi-res .ico files in Gimp
- 使用python脚本抓取百度fm中的歌曲
- 黑马程序员 对象序列化
- 工作中需要做的更好的事项
- Pro Android学习笔记(二八):用户界面和控制(16):GridLayout
- DispatcherServlet
- 解决ArcSDE图层名被占用的问题
- PL/SQ连接oracle数据库的问题,ORA-12154: TNS:could not resolve the connect identifier specified 错误
- python eventlet并发原理分析
- IQiyi sdk
- 007趣味——微软面试海盗分宝石+飞机加油