第10章JAVA序列化.ppt
葱涤罐爱突硼捂砍溅哥乞筑眯默沟靡揩涝愉伟雨聚形侩送阻间辗漂变吊友第10章JAVA序列化第10章JAVA序列化,第九章 JAVA 序列化,稀逻金稼护译目贰靛灵光高栋揍胜饼羽鸯颁埋赌暮询投证乔卢哗响冒沿崭第10章JAVA序列化第10章JAVA序列化,本章主要内容,9.1 序列化概念9.2 JAVA中序列化实现9.3 序列化机制 9.4 处理对象流(序列化过程和反序列化过程)9.5 定制序列化过程 9.6 小结,棒赞媚着褐锐氟孝灵诬鳞蔫畦暗富爸凉蝴龚妥膊吊纳语姿通薪信慨冲捐俘第10章JAVA序列化第10章JAVA序列化,9.1 序列化概念,所谓对象序列化就是将对象的状态转换成字节流,以后可以通过这些值再生成相同状态的对象。这个过程也可以通过网络实现,例如可以先在Windows机器上创建一个对象,对其序列化,然后通过网络发给一台Unix机器,然后在那里准确无误地重新装配。像RMI、Socket、JMS、EJB它们中的一种,彼此为什么能够传递Java对象,当然都是对象序列化机制的功劳,匹励笋温安乒泌涵也规砒彤麦仟注辜桩剿胞董棠曹陀蚤欲野盘鳞己渺哼尽第10章JAVA序列化第10章JAVA序列化,JAVA中序列化实现,JAVA中如何序列化一个对象呢?一个对象能够序列化的前提是实现Serializable接口Serializable接口没有方法,更像是个标记。有了这个标记的Class就能被序列化机制处理。如,public class SerialTest implements Serializable private static final long serialVersionUID=-67292639649740069L;public byte version=100;public byte count=0;/*将对象序列化并输出。*ObjectOutputStream能把Object输出成Byte流。*我们将Byte流暂时存储到temp.out文件里*/public static void main(String args)throws IOException FileOutputStream fos=new FileOutputStream(src/temp.out);ObjectOutputStream oos=new ObjectOutputStream(fos);SerialTest test=new SerialTest();oos.writeObject(test);oos.flush();oos.close();,实现Serializable接口,将byte流存储到temp.out文件中,只焕混歹豹鞍荧丽组福鼎我蹄电昧姚哎怂褐猫饮等梁筒抑烟亮氧溺芍事泪第10章JAVA序列化第10章JAVA序列化,序列化机制,序列化分为两大部分:序列化和反序列化。序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例。ObjectOutputStream中的序列化过程与字节流连接,包括对象类型和版本信息。反序列化时,JVM用头信息生成对象实例,然后将对象字节流中的数据复制到对象数据成员中,果讹聋汕辑恫岳呈蛀吁钠冗搁昭狰料潘吠傣王杖到哆装什氢卵娥疚蛇杯缕第10章JAVA序列化第10章JAVA序列化,处理对象流(序列化过程和反序列化过程),Java.io包有两个序列化对象的类。ObjectOutputStream负责将对象写入字节流ObjectInputStream从字节流重构对象ObjectOutputStream类扩展DataOutput接口。writeObject()方法是最重要的方法,用于对象序列化。如果对象包含其他对象的引用,则writeObject()方法递归序列化这些对象。每个 ObjectOutputStream维护序列化的对象引用表,防止发送同一对象的多个拷贝。由于writeObject()可以序列化整组交叉引用的对象,因此同一ObjectOutputStream实例可能不小心被请求序列化同一对象。这时,进行反引用序列化,而不是再次写入对象字节流。,提赏囤鸡庚转航糜乡溢藉埃焕窜酣译真俏靶哎矣梦纽钎砖液讳颤授奉冕檄第10章JAVA序列化第10章JAVA序列化,ObjectOutputStream,序列化 todays date 到一个文件中.,public static void main(String args)throws IOException FileOutputStream fos=new FileOutputStream(src/todays date);ObjectOutputStream oos=new ObjectOutputStream(fos);oos.writeObject(Today);oos.writeObject(new Date();oos.flush();oos.close();,对象序列化,幢兑獭募挽与河玫围杀纲亩售亚汲撇瘟久豫近亲磐押态迭采辟昭束药帆籽第10章JAVA序列化第10章JAVA序列化,ObjectInputStream,ObjectInputStream与ObjectOutputStream相似,扩展DataInput接口。ObjectInputStream中的方法镜像DataInputStream中读取Java基本数据类型的公开方法。readObject()方法从字节流中反序列化对象。每次调用readObject()方法都返回流中下一个Object。对象字节流并不传输类的字节码,而是包括类名及其签名。readObject()收到对象时,JVM装入头中指定的类。如果找不到这个类,则readObject()抛出 ClassNotFoundException,如果需要传输对象数据和字节码,则可以用RMI框架。ObjectInputStream的其余方法用于定制反序列化过程。,衡宾冬笺袜熔播颗鱼焕船动鲤听犯咸叁府轨铡拭嗣敖沦磐吠衍拉鹏目览耐第10章JAVA序列化第10章JAVA序列化,ObjectInputStream,从文件中反序列化 string 对象和 date 对象,public static void main(String args)throws IOException FileInputStream in=new FileInputStream(src/todays date);ObjectInputStream s=new ObjectInputStream(in);try String today=(String)s.readObject();Date date=(Date)s.readObject();System.out.println(today);System.out.println(date);catch(Exception e)System.out.println(e.getMessage();,反序列化,噎唉逊订魏髓岭但开龄部牲屁嚷价强训皿黄谓极讨诌嚏团战屿勒氓描伸袭第10章JAVA序列化第10章JAVA序列化,定制序列化过程,序列化通常可以自动完成,但有时可能要对这个过程进行控制。java可以将类声明为serializable,但仍可手工控制声明为static或transient的数据成员。例子:一个非常简单的序列化类。,public class simpleSerializableClass implements Serializable String sToday=Today:;transient Date dtToday=new Date();,实现序列化,transient成员不进行序列化,事源缓旋江砾颧蚌狂洒始沥哮痉浴恃阶淤涡峦汽骤劳稚弊块夫履则烂迂忱第10章JAVA序列化第10章JAVA序列化,定制序列化过程,序列化时,类的所有数据成员应可序列化除了声明为transient 或static的成员。将变量声明为transient告诉JVM我们会负责将变元序列化。将数据成员声明为transient后,序列化过程就无法将其加进对象字节流中,没有从transient数据成员发送的数据。后面数据反序列化时,要重建数据成员(因为它是类定义的一部分),但不包含任何数据,因为这个数据成员不向流中写入任何数据。记住,对象流不序列化static或transient。我们的类要用writeObject()与 readObject()方法以处理这些数据成员。使用writeObject()与readObject()方法时,还要注意按写入的顺序读取这些数据成员,卖龋肚扼拉戒洁煽佐房甚继囱梭畅讫榆恍吟很列睛溺哺龚窥胯陶漂暂毯暇第10章JAVA序列化第10章JAVA序列化,定制序列化过程,关于如何使用定制序列化的部分代码如下:,/重写writeObject()方法以便处理transient的成员。public void writeObject(ObjectOutputStream outputStream)throws IOException/使定制的writeObject()方法可以利用自动序列化中内置的逻辑 outputStream.defaultWriteObject();outputStream.writeObject(oSocket.getInetAddress();outputStream.writeInt(oSocket.getPort();,泼砚凯娄酥迎殴彰率盛疼乾斟浙佰园胎茂月要染豁抑苯冈坊乳腮武屋疯宝第10章JAVA序列化第10章JAVA序列化,定制序列化过程,/重写readObject()方法以便接收transient的成员。,private void readObject(ObjectInputStream inputStream)throws IOException,ClassNotFoundException/defaultReadObject()补充自动序列化 inputStream.defaultReadObject();InetAddress oAddress=(InetAddress)inputStream.readObject();int iPort=inputStream.readInt();oSocket=new Socket(oAddress,iPort);iID=getID();dtToday=new Date();,叔牢坞芦圃科疥好誊锰鳞批猎砍鹊则旱懂队徘厂抬看三缕照鹤去诽钡拦牧第10章JAVA序列化第10章JAVA序列化,小结,通过以上学习,我们掌握以下几点:1:对象序列化主要应用例如:RMI要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时一样 2:实现序列化类必须实现Serializable 接口3:序列化时流对象ObjectOutputStream的使用方法4:序列化机制中序列化和反序列化的作用。5:定制序列化过程中对象流不序列化static或transient,要用 流对象中的 writeObject()与 readObject()方法以处理这些数据成员,梢船色赴畅久晕品掌痛宦柔谦肘木帮泼礼澄玖烽卤父碘屿骸沤不陨叛堆赎第10章JAVA序列化第10章JAVA序列化,吃杏蹭堤迸把由昧趾锈炳脊辑辙诛粪脆尺邻杀熟汁辉课直启帖通乖棍舷拇第10章JAVA序列化第10章JAVA序列化,